Angular Forms 簡介
Angular 4 中有兩種表單:
- Template Driven Forms - 模板驅動式表單 (類似於 AngularJS 1.x 中的表單 )
- Reactive Forms - 響應式表單
1 - 創建最簡單的輸入框
如何實現雙向綁定?
在 Angular 表單中,我們通過 ngModel
指令來實現雙向綁定。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<input type="text" [(ngModel)]="username">
{{username}}
`,
})
export class AppComponent {
username = 'semlinker';
}
2 - 添加簡單的驗證功能
如何爲表單控件添加驗證功能?
目前 Angular 支持的內建 validators
如下:
- required - 設置表單控件值是非空的
- email - 設置表單控件值的格式是 email
- minlength - 設置表單控件值的最小長度
- maxlength - 設置表單控件值的最大長度
- pattern - 設置表單控件的值需匹配 pattern 對應的模式
接下來我們來添加最簡單的 必填
校驗。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<input
type="text"
required
[(ngModel)]="username">
{{username}}
`,
})
export class AppComponent {
username = 'semlinker';
}
如何判斷表單控件是否通過驗證?
在 Angular 中,我們可以通過 #userName="ngModel"
方式獲取 ngModel
對象,然後通過 userName.valid
判斷表單控件是否通過驗證。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<input
type="text"
required
[(ngModel)]="username"
#userName="ngModel">
{{userName.valid}}
`,
})
export class AppComponent {
username = 'semlinker';
}
3 - 顯示驗證失敗的錯誤信息
如何顯示驗證失敗的錯誤信息?
在 Angular 中,我們可以通過 #userName="ngModel"
方式獲取 ngModel
對象,然後通過該對象的 errors
屬性,來獲取對應驗證規則 (如 required, minlength 等) 的驗證狀態。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<input
type="text"
required
minlength="3"
[(ngModel)]="username"
#userName="ngModel">
<hr>
<div *ngIf="userName.errors?.required">請您輸入用戶名</div>
<div *ngIf="userName.errors?.minlength">
用戶名的長度必須大於 {{userName.errors?.minlength.requiredLength}},當前的長度爲
{{userName.errors?.minlength.actualLength}}
</div>
`,
})
export class AppComponent {
username = 'semlinker';
}
4 - 創建表單
如何使用表單?
在 Angular 中,我們可以使用熟悉的 <form>
標籤來創建表單。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<form>
<input
type="text"
required
minlength="3"
name="username"
[(ngModel)]="username"
#userName="ngModel">
<hr>
<div *ngIf="userName.errors?.required">請您輸入用戶名</div>
<div *ngIf="userName.errors?.minlength">
用戶名的長度必須大於 {{userName.errors?.minlength.requiredLength}},當前的長度爲
{{userName.errors?.minlength.actualLength}}
</div>
<button type="submit">提交</button>
</form>
`,
})
export class AppComponent {
username = 'semlinker';
}
需要注意的是,在使用 <form>
標籤後,我們的 username
輸入框,必須添加 name
屬性。
如何獲取表單提交的值?
在 Angular 中,我們可以通過 #loginForm="ngForm"
方式獲取 ngForm
對象,然後通過 loginForm.value
來獲取表單的值。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<form #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm.value)">
<input
type="text"
required
minlength="3"
name="username"
[(ngModel)]="username"
#userName="ngModel">
<hr>
<div *ngIf="userName.errors?.required">請您輸入用戶名</div>
<div *ngIf="userName.errors?.minlength">
用戶名的長度必須大於 {{userName.errors?.minlength.requiredLength}},當前的長度爲
{{userName.errors?.minlength.actualLength}}
</div>
<button type="submit">提交</button>
{{loginForm.value | json}}
</form>
`,
})
export class AppComponent {
username = 'semlinker';
onSubmit(value) {
console.dir(value);
}
}
5 - ngModelGroup簡介
ngModelGroup 有什麼作用?
ngModelGroup 指令是 Angular 表單中提供的另一特殊指令,可以對錶單輸入內容進行分組,方便我們在語義上區分不同性質的輸入。例如聯繫人的信息包括姓名及住址,現在需對姓名和住址進行精細化信息收集,姓名可精細化成姓和名字,地址可精細化成城市、區、街等。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<form #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm.value)">
<fieldset ngModelGroup="user">
<input
type="text"
required
minlength="3"
name="username"
[(ngModel)]="username"
#userName="ngModel">
<hr>
<div *ngIf="userName.errors?.required">請您輸入用戶名</div>
<div *ngIf="userName.errors?.minlength">
用戶名的長度必須大於 {{userName.errors?.minlength.requiredLength}},當前的長度爲
{{userName.errors?.minlength.actualLength}}
</div>
<input type="password" ngModel name="password">
</fieldset>
<button type="submit">提交</button>
<hr>
{{loginForm.value | json}}
</form>
`,
})
export class AppComponent {
username = 'semlinker';
onSubmit(value) {
console.dir(value);
}
}
以上代碼成功運行後,{{loginForm.value | json}}
的輸出結果:
{ "user": { "username": "semlinker", "password": "123" } }
6 - 表單添加驗證狀態樣式
如何爲表單添加驗證狀態樣式信息?
在 Angular 表單中,若驗證通過則會在表單控件上添加 ng-valid
類,若驗證失敗則會在表單控件上添加 ng-invalid
類。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
styles: [`
input.ng-invalid {
border: 3px solid red;
}
input.ng-valid {
border: 3px solid green;
}
`
],
template: `
<form #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm.value)">
<fieldset ngModelGroup="user">
<input
type="text"
required
minlength="3"
name="username"
[(ngModel)]="username"
#userName="ngModel">
<hr>
<div *ngIf="userName.errors?.required">請您輸入用戶名</div>
<div *ngIf="userName.errors?.minlength">
用戶名的長度必須大於 {{userName.errors?.minlength.requiredLength}},當前的長度爲
{{userName.errors?.minlength.actualLength}}
</div>
<input type="password" required ngModel name="password">
</fieldset>
<button type="submit">提交</button>
<hr>
{{loginForm.value | json}}
</form>
`,
})
export class AppComponent {
username = 'semlinker';
onSubmit(value) {
console.dir(value);
}
}
7 - 表單控件的狀態
表單控件除了 valid
狀態外,還包含哪些狀態?
在 Angular 中表單控件有以下 6 種狀態,我們可以通過 #userName="ngModel"
方式獲取 ngModel
對象,進而獲取控件的狀態信息。具體狀態如下:
- valid - 表單控件有效
- invalid - 表單控件無效
- pristine - 表單控件值未改變
- dirty - 表單控件值已改變
- touched - 表單控件已被訪問過
- untouched - 表單控件未被訪問過
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
styles: [`
input.ng-invalid {
border: 3px solid red;
}
input.ng-valid {
border: 3px solid green;
}
`
],
template: `
<form #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm.value)">
<fieldset ngModelGroup="user">
<input
type="text"
required
minlength="3"
name="username"
[(ngModel)]="username"
#userName="ngModel">
<hr>
<p>Name控件的valid狀態:{{userName.valid}} - 表示控件有效</p>
<p>Name控件的invalid狀態:{{userName.invalid}} - 表示控件無效</p>
<p>Name控件的pristine狀態:{{userName.pristine}} - 表示控件值未改變</p>
<p>Name控件的dirty狀態:{{userName.dirty}} - 表示控件值已改變</p>
<p>Name控件的touched狀態:{{userName.touched}} - 表示控件已被訪問過</p>
<p>Name控件的untouched狀態:{{userName.untouched}} - 表示控件未被訪問過</p>
<div *ngIf="userName.errors?.required">請您輸入用戶名</div>
<div *ngIf="userName.errors?.minlength">
用戶名的長度必須大於 {{userName.errors?.minlength.requiredLength}},當前的長度爲
{{userName.errors?.minlength.actualLength}}
</div>
<input type="password" required ngModel name="password">
</fieldset>
<button type="submit">提交</button>
<hr>
{{loginForm.value | json}}
</form>
`,
})
export class AppComponent {
username = 'semlinker';
onSubmit(value) {
console.dir(value);
}
}
8 - 使用單選控件
如何添加單選控件?
在 Angular 中,我們通過 <input name="***" type="radio">
方式添加單選控件。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<form #loginForm="ngForm">
Angular版本:
<div *ngFor="let version of versions;">
<input
[attr.id]="version"
name="version"
ngModel
required
[value]="version"
type="radio">
<label [attr.for]="version">{{version}}</label>
</div>
<hr>
{{loginForm.value | json}}
</form>
`,
})
export class AppComponent {
versions = ['1.x', '2.x', '3.x'];
}
9 - 使用多選控件
如何添加多選控件?
在 Angular 中,我們通過 <select name="***">
方式添加多選控件。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<form #loginForm="ngForm">
Angular版本:
<select name="version" [ngModel]="versions[0]">
<option
*ngFor="let version of versions;"
[value]="version">
{{version}}
</option>
</select>
<hr>
{{loginForm.value | json}}
</form>
`,
})
export class AppComponent {
versions = ['1.x', '2.x', '3.x'];
}
如何添加必填驗證?
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
styles: [`
select.ng-invalid + label:after {
content: '<-- 請選擇版本!'
}
`
],
template: `
<form #loginForm="ngForm">
Angular版本:
<div>
<select name="version" [ngModel]="version" required>
<option
*ngFor="let version of versions;"
[value]="version">
{{version}}
</option>
</select>
<label></label>
</div>
<hr>
{{loginForm.value | json}}
</form>
`,
})
export class AppComponent {
versions = ['','1.x', '2.x', '3.x'];
}