最近工作比較忙,一直沒有更新文章。原來看別人的文章感覺很過癮,現在自己寫才發現,要堅持下去真的很難。好了,廢話少說,繼續吧!
這一章主要講利用angularJs控制使用者登入。在前面的使用者登錄檔單中使用了angular的響應式表單。為了對angular的知識學習的全面一點,在使用者登入的表單中,使用了模板驅動型表單。
先從html程式碼開始
<div class="div-login">
<form (ngSubmit)="onSubmit()" #loginForm="ngForm">
<div class="form-group">
<label for="name">User name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Enter user name" [(ngModel)]="user.name" required
#name="ngModel">
<div *ngIf="name.invalid && (name.dirty || name.touched)" class="alert alert-danger">
User name is required!
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<div class="input-group">
<input class="form-control" id="password" name="passwrod" placeholder="Enter password" [(ngModel)]="user.password"
required #password="ngModel">
</div>
<div *ngIf="password.invalid && (password.dirty || password.touched)" class="alert alert-danger">
Password is required!
</div>
</div>
<div class="form-group form-btn">
<button type="submit" class="btn btn-primary" [disabled]="!loginForm.form.valid">Submit</button>
<button type="button" class="btn btn-light" (click)="loginForm.reset()">Cancel</button>
</div>
</form>
</div>
在這個html檔案的<form>標籤中,(ngSubmit)="onSubmit()"
和使用者登錄檔單一樣,用於處理表單的提交操作,為了實現在表單不合法時提交按鈕的disabled為false,需要讓按鈕能夠訪問到表單,從而獲取到表單的狀態,所以,需要在<form>標籤中定義了一個模板引用變數 #loginForm,並且把賦值為“ngForm”,同時在submit按鈕標籤中加入:[disabled]="!loginForm.form.valid"
。
兩個<input>標籤分別輸入使用者名稱和密碼,通過ngModel建立雙向繫結到元件類的User物件的name和password屬性,用於讀取和寫入輸入控制元件的值。這裡需要注意一點:當在表單中使用 [(ngModel)] 時,必須要定義 name 屬性。
模板驅動表單的驗證都在html程式碼中實現,需要完成以下幾項任務:
- 首先要定義模板引用變數,並賦值為”ngModel”,注意觀察<input>標籤中的 #name=”ngModel”和#password=”ngModel”。
- 兩個使用者名稱和密碼的驗證規則比較簡單,只需required,在兩個<input>標籤中加入此屬性。
- 顯示驗證錯誤資訊和登錄檔單差不多,當模板引用變數即兩個輸入框變為dirty(控制元件值變化了)和touched(控制元件值被訪問過)狀態時,如果控制元件值無效(invalid),就顯示<div>標籤包裹的內容。
html部分的內容就這些了,下面我們看一下控制元件類的內容。
控制元件類
先把程式碼放出來,後面慢慢分析。
@Component({
selector: `app-login`,
templateUrl: `./login.component.html`,
styleUrls: [`./login.component.css`]
})
export class LoginComponent {
user: User = new User(0, ``, ``, ``);
constructor(
private route: Router,
private jumService: JumbotronServive,
private userServ: UserService,
private tokenServ: AuthTokenService) {
jumService.setJumbotron(new Jumbotron(`Login`,
`Please login with your user name and password first`,
``));
}
onSubmit() {
this.userServ.getUser(this.user).subscribe(
(resp) => {
this.tokenServ.setToken(resp.body[`token`]);
this.route.navigate([`/birthday`]);
alert(`登入成功!`);
},
(err)=>
alert(this.userServ.handleError(err)),
() => console.log(`The Post observable is now completed. `)
)
}
}
控制元件類主要完成了如下功能:
- 首先初始化了一個User類的物件,用於ngModel雙向繫結到控制元件。保證在html控制元件值變化時,繫結的User類的屬性同步變化。
- 在建構函式中宣告瞭一個Router物件、一個JumbotronServive物件和UserService物件、AuthTokenService物件。並在建構函式中用JumbotronServive的setJumbotron方法更新了網頁的標題。(JumbotronServive的setJumbotron方法具體內容請看前面的文章。)
- onSubmit()函式在表單提交時被觸發,在該函式中UserService的getUser()函式,getUser()函式向伺服器傳送了使用者名稱和密碼,如果伺服器驗證成功,會傳送回jwt認證資訊的token字串,其中包括了userid。在onSubmit()函式中呼叫AuthTokenService的setToken()函式,將這個字串儲存到本地儲存,用於導航到下一個頁面(生日頁面)時驗證使用者資訊。接下來導航到下一個頁面,並提示使用者登入成功。如果發生錯誤,提示錯誤原因。
使用者登入主要的內容就這些了。其中還有一個小技巧性的東西就是在輸入密碼的時候,因為<input>標籤的type=password,顯示的輸入內容為“.”,很容易輸錯。我在這個控制元件上放了一個可以切換的圖片,用於讓使用者選擇是否檢視明文。實現的方法主要是改變<input>控制元件的attr屬性。如果需要具體實現方法的朋友,可以給我留言,我會在回覆中告訴大家。