本教程的開(kāi)發(fā)環(huán)境及開(kāi)發(fā)語(yǔ)言:
npm install -g @angular/cli
ng new PROJECT-NAME
cd PROJECT-NAME
ng serve
Angular 4 中有兩種表單:
本文主要介紹 Template Driven Forms (模板驅(qū)動(dòng)式表單) 的基礎(chǔ)知識(shí),相關(guān)的知識(shí)點(diǎn)會(huì)以問(wèn)答的形式進(jìn)行介紹。
在 Angular 表單中,我們通過(guò) ngModel
指令來(lái)實(shí)現(xiàn)雙向綁定。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<input type="text" [(ngModel)]="username">
{{username}}
`,
})
export class AppComponent {
username = 'semlinker';
}
目前 Angular 支持的內(nèi)建 validators
如下:
接下來(lái)我們來(lái)添加最簡(jiǎn)單的 必填
校驗(yàn)。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<input
type="text"
required
[(ngModel)]="username">
{{username}}
`,
})
export class AppComponent {
username = 'semlinker';
}
在 Angular 中,我們可以通過(guò) #userName="ngModel"
方式獲取 ngModel
對(duì)象,然后通過(guò) userName.valid
判斷表單控件是否通過(guò)驗(yàn)證。
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';
}
在 Angular 中,我們可以通過(guò) #userName="ngModel"
方式獲取 ngModel
對(duì)象,然后通過(guò)該對(duì)象的 errors
屬性,來(lái)獲取對(duì)應(yīng)驗(yàn)證規(guī)則 (如 required, minlength 等) 的驗(yàn)證狀態(tài)。
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">請(qǐng)您輸入用戶名</div>
<div *ngIf="userName.errors?.minlength">
用戶名的長(zhǎng)度必須大于 {{userName.errors?.minlength.requiredLength}},當(dāng)前的長(zhǎng)度為
{{userName.errors?.minlength.actualLength}}
</div>
`,
})
export class AppComponent {
username = 'semlinker';
}
在 Angular 中,我們可以使用熟悉的 <form>
標(biāo)簽來(lái)創(chuàng)建表單。
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">請(qǐng)您輸入用戶名</div>
<div *ngIf="userName.errors?.minlength">
用戶名的長(zhǎng)度必須大于 {{userName.errors?.minlength.requiredLength}},當(dāng)前的長(zhǎng)度為
{{userName.errors?.minlength.actualLength}}
</div>
<button type="submit">提交</button>
</form>
`,
})
export class AppComponent {
username = 'semlinker';
}
需要注意的是,在使用 <form>
標(biāo)簽后,我們的 username
輸入框,必須添加 name
屬性。
在 Angular 中,我們可以通過(guò) #loginForm="ngForm"
方式獲取 ngForm
對(duì)象,然后通過(guò) loginForm.value
來(lái)獲取表單的值。
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">請(qǐng)您輸入用戶名</div>
<div *ngIf="userName.errors?.minlength">
用戶名的長(zhǎng)度必須大于 {{userName.errors?.minlength.requiredLength}},當(dāng)前的長(zhǎng)度為
{{userName.errors?.minlength.actualLength}}
</div>
<button type="submit">提交</button>
{{loginForm.value | json}}
</form>
`,
})
export class AppComponent {
username = 'semlinker';
onSubmit(value) {
console.dir(value);
}
}
ngModelGroup 指令是 Angular 表單中提供的另一特殊指令,可以對(duì)表單輸入內(nèi)容進(jìn)行分組,方便我們?cè)谡Z(yǔ)義上區(qū)分不同性質(zhì)的輸入。例如聯(lián)系人的信息包括姓名及住址,現(xiàn)在需對(duì)姓名和住址進(jìn)行精細(xì)化信息收集,姓名可精細(xì)化成姓和名字,地址可精細(xì)化成城市、區(qū)、街等。
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">請(qǐng)您輸入用戶名</div>
<div *ngIf="userName.errors?.minlength">
用戶名的長(zhǎng)度必須大于 {{userName.errors?.minlength.requiredLength}},當(dāng)前的長(zhǎng)度為
{{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);
}
}
以上代碼成功運(yùn)行后,{{loginForm.value | json}}
的輸出結(jié)果:
{ "user": { "username": "semlinker", "password": "123" } }
在 Angular 表單中,若驗(yàn)證通過(guò)則會(huì)在表單控件上添加 ng-valid
類(lèi),若驗(yàn)證失敗則會(huì)在表單控件上添加 ng-invalid
類(lèi)。
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">請(qǐng)您輸入用戶名</div>
<div *ngIf="userName.errors?.minlength">
用戶名的長(zhǎng)度必須大于 {{userName.errors?.minlength.requiredLength}},當(dāng)前的長(zhǎng)度為
{{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);
}
}
valid
狀態(tài)外,還包含哪些狀態(tài)?
在 Angular 中表單控件有以下 6 種狀態(tài),我們可以通過(guò) #userName="ngModel"
方式獲取 ngModel
對(duì)象,進(jìn)而獲取控件的狀態(tài)信息。具體狀態(tài)如下:
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狀態(tài):{{userName.valid}} - 表示控件有效</p>
<p>Name控件的invalid狀態(tài):{{userName.invalid}} - 表示控件無(wú)效</p>
<p>Name控件的pristine狀態(tài):{{userName.pristine}} - 表示控件值未改變</p>
<p>Name控件的dirty狀態(tài):{{userName.dirty}} - 表示控件值已改變</p>
<p>Name控件的touched狀態(tài):{{userName.touched}} - 表示控件已被訪問(wèn)過(guò)</p>
<p>Name控件的untouched狀態(tài):{{userName.untouched}} - 表示控件未被訪問(wèn)過(guò)</p>
<div *ngIf="userName.errors?.required">請(qǐng)您輸入用戶名</div>
<div *ngIf="userName.errors?.minlength">
用戶名的長(zhǎng)度必須大于 {{userName.errors?.minlength.requiredLength}},當(dāng)前的長(zhǎng)度為
{{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);
}
}
在 Angular 中,我們通過(guò) <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'];
}
在 Angular 中,我們通過(guò) <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: '<-- 請(qǐng)選擇版本!'
}
`
],
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'];
}
更多建議: