最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

Angular 網站實例 – 使用者服務篇

XAMPP下载 admin 826浏览 0评论
 Angular 網站實例 – 使用者服務篇
今天開始 今天完成

今天的目標:完成使用者服務,讓使用者登入畫面能夠透過使用者服務來連結後端

QQ截图20181009164847
 設定使用者服務 (User Service)
第一步:在使用者模組下建立目錄 /src/app/user/service

mkdir service
第二步:產生使用者服務

ng generate service user –module user
使用 –module user,angular-cli 會主動將這個服務加入模組成為 provider,這個服務是全域的服務,也就是所有的元件 (component) 都可以使用。

第三步:加入後端網址,在 src/app/share 下加入

ng generate class app.config
第四步:修改 app.config.ts

export class AppConfig {
public readonly apiUrl = ‘http://localhost:3000/api’;
}
第五步:加入 share 模組

// … 省略
import { AppConfig } from ‘./app.config’;

// … 省略
@NgModule({
// …
providers: [AppConfig]

})
第六步: share 模組加入 indext.ts

export * from ‘./share.module’;
export * from ‘./app.config’;
設定介面 (Interface)
我們來增加兩個介面:使用者跟後端回應的介面
第一步:先造一個目錄 src/app/models

mkdir models
第二步:用 angular-cli 產生使用者介面

ng generate interface user
第三步:修改 user.ts

export interface User {
username: string;
password?: string;
rememberMe?: boolean;
}
第四步:用 angular-cli 產生後端回應介面

ng generate interface response
第五步:修改 response.ts

export interface Response {
success: boolean;
payload?: any;
}
第六步:建立 index.ts 在 src/app/models 下,這樣在元件做 import 時,只要指到這個目錄即可
src/app/models/index.ts

export * from ‘./user’;
export * from ‘./response’;
加入 HttpClient 模組
在 src/app/user/user.module.ts 加入

//… 省略
import { HttpClientModule } from ‘@angular/common/http’;
// … 省略
@NgModule({
imports: [
CommonModule,
UserRoutingModule,
ShareModule,
HttpClientModule
],
declarations: [LoginComponent],
providers: [UserService]
})
export class UserModule { }
使用者服務
這個服務要提供:使用者登入狀態及使用者名稱,我們會用到 BehaviorSubject 這個 Observable 來做,因為這些狀態隨時會改變。 直接看程式

import { Injectable } from ‘@angular/core’;
import { HttpClient, HttpErrorResponse } from ‘@angular/common/http’;

import { AppConfig } from ‘../../share’;
import { User, Response } from ‘../../models’;

import { Observable } from ‘rxjs/Observable’;
import { BehaviorSubject } from ‘rxjs/BehaviorSubject’;
import ‘rxjs/add/operator/map’;
import { of } from ‘rxjs/observable/of’;

@Injectable()
export class UserService {
loginStatus = new BehaviorSubject<boolean>(false);
currentUser = new BehaviorSubject<User>(null);
constructor(
private http: HttpClient,
private appConfig: AppConfig
) { }

loginServer(loginData): Observable<Response> {
let username = loginData.username.trim();
let password = loginData.password.trim();
return this.http.post<Response>(this.appConfig.apiUrl + ‘/users/authenticate’, { username: username, password: password });
}
login(loginData): Observable<boolean> {
return this.loginServer(loginData)
.map((res: Response) => {
if (res.success) {
this.loginStatus.next(true);
this.currentUser.next(loginData.username);
return true;
} else {
console.log(‘can not login’);
return false;
}
},
(err: HttpErrorResponse) => {
if (err.error instanceof Error) {
console.log(‘client-side error’);
} else {
console.log(‘server-side error’);
}
return of(false);
})
}
logout() {
this.loginStatus.next(false);
this.currentUser.next(null);

     }
getLoginStatus(): Observable<boolean> {
return this.loginStatus;
}
getCurrentUser(): Observable<User> {
return this.currentUser;
}
}
建立 loginStatus$ 跟 currentUser$ BehaviorSubject
導入 HttpClient 跟 AppConfig
loginServer() 使用 http.post() 跟後端連結。
login()使用 loginServer() subscribe 後端的回應,如果成功,將 loginStatus$ 跟 currentUser$ push 給訂閱者 (Subscribers)
logout() 將 loginStatus$ 跟 currentUser$ 回到原來狀態
最後提供兩個介面 getLoginStatus() 跟 getCurrentUser() 給元件使用
完成使用者服務後,我們來更新一下它的用戶: login 跟 navbar 元件

更新使用者登入元件 (login)
[ngrx/store-17] Angular 網站實例 – 使用者登入篇已經完成登入畫面,我們只要在做 submit() 時呼叫 login() 函數

//… 省略
import { UserService } from ‘..rvice/user.service’;
import { MatSnackBar } from ‘@angular/material’;
//…
constructor(
private fb: FormBuilder,
private userService: UserService,
private snackbar: MatSnackBar
) { }

//…
login() {
this.userService.login(this.form.value)
.subscribe(res => {
if (res) {
this.snackbar.open(‘登入成功’, ‘OK’, { duration: 3000});
} else {
this.snackbar.open(‘請檢查使用者名稱及密碼’, ‘OK’, {duration: 3000});
}
})
}
導入 UserService,將表格資料傳給 UserService,登入成功時,用 @angular/materail 的 snackbar顯示成功訊息,否則顯示失敗訊息。使用者可以按 OK 來取消訊息或者等 3 秒就會自動消失。

更新瀏覽列 (Navbar)
第一步:修改 navbar.component.ts
直接看程式

import { Component, OnInit } from ‘@angular/core’;
import { Router } from ‘@angular/router’;

import { Observable } from ‘rxjs/Observable’;
import ‘rxjs/add/observable/of’;

import { UserService } from ‘../userrvice/user.service’;
import { User } from ‘../models’;

@Component({
selector: ‘app-navbar’,
templateUrl: ‘./navbar.component.html’,
styleUrls: [‘./navbar.component.css’]
})
export class NavbarComponent implements OnInit {
login$: Observable<boolean>;
user$: Observable<User>;
constructor(
private userService: UserService,
private router: Router
) { }
ngOnInit() {
//this.login$ = Observable.of(true);
this.login$ = this.userService.getLoginStatus();
this.user$ = this.userService.getCurrentUser();
}
logout() {
//this.login$ = Observable.of(false);
this.userService.logout();
this.router.navigate([‘/’])
}
}
加入 user$ Observable
導入 Router 跟 UserService
在 ngOnInit() 設定 login$ 跟 user$ 兩個 Observable
我們也稍微修改一下畫面,在瀏覽列加入登入的使用者名稱

第二步:加入新的 Material
先加入 mat-menu,mat-icon 跟前面的 matSanckBar 到 share module

//… 省略
import { MatInputModule, MatIconModule, MatMenuModule, MatSnackBarModule } from ‘@angular/material’;

// … 省略
@NgModule({
imports: [
// …
MatInputModule,
MatMenuModule,
MatSnackBarModule,
//…
],
exports: [
//…
MatInputModule,
MatMenuModule,
MatSnackBarModule,
//…
]
})
第三步:修改 navbar.component.html
如下:

<mat-toolbar  [style.background] = “(login$ | async) ? ‘darkviolet’ : ‘seagreen'” class=”navbar”>
<a mat-button routerLink=”/”>洋蔥投顧</a>
<span class=”to-right”></span>
<a mat-button *ngIf=”!(login$| async)” routerLink=”/user/login”>會員登入</a>
<a mat-button *ngIf=”login$ | async” routerLink=””>會員中心</a>
<button *ngIf=”user$ | async ” mat-button [matMenuTriggerFor]=”userMenu”>
<span>{{user$ | async}}</span> <mat-icon>arrow_drop_down</mat-icon>
<tton>
</mat-toolbar>
<!– User sub menu –>
<mat-menu x-position=”before” #userMenu=”matMenu”>
<button mat-menu-item >帳號<tton>
<button mat-menu-item (click)=”logout()” >會員登出<tton>
</mat-menu>
當有使用者的時候,接下一個子選單 (sub menu),裡面包含 帳號,會員登出。

完成後截圖如下
登入成功

QQ截图20181009164928
QQ截图20181009164935
QQ截图20181009164941
到這裡,我們大概完成了使用者登入的動作,但這裡有一個問題,如果使用者重新刷瀏覽器,會重回未登入狀態,我們下次來解決這個問題。

转载请注明:XAMPP中文组官网 » Angular 網站實例 – 使用者服務篇

您必须 登录 才能发表评论!