angular6的響應(yīng)式表單的實(shí)現(xiàn)
1:在AppModule模塊里面引入 ReactiveFormsModule
要使用響應(yīng)式表單,就要從@angular/forms包中導(dǎo)入ReactiveFormsModule,并把它添加到你的NgModule的imports數(shù)組中。
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [
// other imports ...
ReactiveFormsModule
],
})
export class AppModule { }
2:創(chuàng)建一個(gè)新的組件
ng g c NameEditor
3:請(qǐng)?jiān)诮M件中導(dǎo)入 FormControl 類(lèi)
FormControl類(lèi)是angular響應(yīng)式表單最基本的構(gòu)造快,要注冊(cè)單個(gè)的表單控件,請(qǐng)?jiān)诮M件中導(dǎo)入FormControl類(lèi),并創(chuàng)建一個(gè)FormControl的新實(shí)例,把它保存在某個(gè)屬性里面。
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
@Component({
selector: 'app-name-editor',
templateUrl: './name-editor.component.html',
styleUrls: ['./name-editor.component.css']
})
export class NameEditorComponent {
name = new FormControl('');
}
4:在組件的模板中注冊(cè)一個(gè)表單控件
修改模板,為表單控件添加 formControl 綁定,formControl 是由 ReactiveFormsModule 中的 FormControlDirective 提供的。
<label>
Name:
<input type="text" [formControl]="name">
</label>
<p>
Value: {{ name.value }}
</p>
使用這種模板綁定語(yǔ)法,把該表單控件注冊(cè)給了模板中名為 name 的輸入元素。這樣,表單控件和 DOM
元素就可以互相通訊了:視圖會(huì)反映模型的變化,模型也會(huì)反映視圖中的變化。
5:替換表單控件的值
FormControl 提供了一個(gè)setValue()方法,他會(huì)修改這個(gè)表單控件的值。
js
updateName() {
this.name.setValue('Nancy');
}
html
<label>
Name:
<input type="text" [formControl]="name">
</label>
<p>
Value:{{name.value}}
</p>
<p>
<button (click)="updateName()">Update Name</button>
</p>
在這個(gè)例子中,你只使用單個(gè)控件FormControl,但是當(dāng)調(diào)用 FormGroup 或 FormArray 的 setValue()方法時(shí),傳入的值就必須匹配控件組或控件數(shù)組的結(jié)構(gòu)才行
6:把表單控件分組
FormControl的實(shí)例能控制單個(gè)輸入框所對(duì)應(yīng)的控件,F(xiàn)ormGroup可以控制一組FormControl實(shí)例的表單狀態(tài),當(dāng)創(chuàng)建FormGroup時(shí),其中的每一個(gè)控件都會(huì)根據(jù)名字進(jìn)行跟蹤
1>:創(chuàng)建新的組件
ng g c ProfileEditor
2>:導(dǎo)入 FormGroup 和 FormControl 類(lèi)并且創(chuàng)建 FormGroup實(shí)例
import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'app-profile-editor',
templateUrl: './profile-editor.component.html',
styleUrls: ['./profile-editor.component.css']
})
export class ProfileEditorComponent {
profileForm = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
});
}
現(xiàn)在這些單獨(dú)的控件FormControl被收集到了一個(gè)控件組中FormGroup, FormGroup 實(shí)例擁有和 FormControl 實(shí)例相同的屬性(比如 value、untouched)和方法(比如 setValue())。
3>:關(guān)聯(lián)FormGroup的模型和視圖
FormGroup能追蹤每個(gè)單獨(dú)控件FormControl的狀態(tài)和變化,如果其中某個(gè)控件的狀態(tài)或值變化了,父控件也會(huì)一次新的狀態(tài)變更或值變更事件
<form [formGroup]="profileForm"> <label> First Name: <input type="text" formControlName="firstName"> </label> <label> Last Name: <input type="text" formControlName="lastName"> </label> </form>
profileForm通過(guò)[formGroup]指令綁定到了 form元素,在該模型和表單中的輸入框之間創(chuàng)建了一個(gè)通訊層,F(xiàn)ormControlName 指令提供的 formControlName 屬性把每個(gè)輸入框和 FormGroup 中定義的表單控件綁定起來(lái)。
4>:關(guān)聯(lián)FormGroup的模型和視圖
html
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()"> <label> First Name: </label> <input type="text" formControlName="firstName"> <label> Last Name: </label> <input type="text" formControlName="lastName"> <button type="submit" >Submit</button> </form>
js
onSubmit () {
console.warn(this.profileForm.value);
}
form 標(biāo)簽所發(fā)出的 submit 事件是原生 DOM 事件,通過(guò)點(diǎn)擊類(lèi)型為 submit 的按鈕可以觸發(fā)本事件
6:嵌套的表單組
js
profileForm = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
address: new FormGroup({
street: new FormControl(''),
city: new FormControl(''),
state: new FormControl(''),
zip: new FormControl('')
})
});
html
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()"> <label> First Name: </label> <input type="text" formControlName="firstName"> <label> Last Name: </label> <input type="text" formControlName="lastName"> <div formGroupName="address"> <label>Streel</label> <input type="text" formControlName="street"> <label>City</label> <input type="text" formControlName="city"> <label>State</label> <input type="text" formControlName="state"> <label>Zip Code</label> <input type="text" formControlName="zip"> </div> <button type="submit" [disabled]="!profileForm.valid">Submit</button> </form>
部分模型修改
html
<button (click)="updateProfile()">Update Profile</button>
js
updateProfile() {
this.profileForm.patchValue({
firstName: 'Nancy',
address: {
street: '123 Drew Street'
}
});
}
patchValue() 方法要針對(duì)模型的結(jié)構(gòu)進(jìn)行更新。patchValue() 只會(huì)更新表單模型中所定義的那些屬性。
6:使用 FormBuilder 來(lái)生成表單控件
FormBuilder 服務(wù)提供了一些便捷方法來(lái)生成表單控件。
FormBuilder在幕后也使用同樣的方式來(lái)創(chuàng)建和返回這些實(shí)例,只是用起來(lái)更簡(jiǎn)單。 下面會(huì)重構(gòu) ProfileEditor 組件,用FormBuilder 來(lái)代替手工創(chuàng)建這些 FormControl 和 FormGroup。
Step 1 - 導(dǎo)入 FormBuilder 類(lèi)
import { FormBuilder } from '@angular/forms';
Step 2 - 注入FormBuild 服務(wù)
constructor(private fb: FormBuilder) { }
Step 3- 生成表單控件
FormBuilder 服務(wù)有三個(gè)方法:control()、group() 和 array()。這些方法都是工廠(chǎng)方法,用于在組件類(lèi)中分別生成
FormControl、FormGroup 和 FormArray。
你可以使用 group() 方法,用和前面一樣的名字來(lái)定義這些屬性。這里,每個(gè)控件名對(duì)應(yīng)的值都是一個(gè)數(shù)組,這個(gè)數(shù)組中的第一項(xiàng)是其初始值。你可以只使用初始值來(lái)定義控件,但是如果你的控件還需要同步或異步驗(yàn)證器,那就在這個(gè)數(shù)組中的第二項(xiàng)和
第三項(xiàng)提供同步和異步驗(yàn)證器。
import { Component } from '@angular/core';
import { FormBuilder } from '@angular/forms';
@Component({
selector: 'app-profile-editor',
templateUrl: './profile-editor.component.html',
styleUrls: ['./profile-editor.component.css']
})
export class ProfileEditorComponent {
profileForm = this.fb.group({
firstName: ['張'],
lastName: ['娉'],
address: this.fb.group({
street: [''],
city: [''],
state: [''],
zip: ['']
}),
});
constructor(private fb: FormBuilder) { }
}
7:簡(jiǎn)單的表單驗(yàn)證
如何把單個(gè)驗(yàn)證器添加到表單控件中,以及如何顯示表單的整體狀態(tài)。
Step 1 - 導(dǎo)入驗(yàn)證器函數(shù)
import { Validators } from '@angular/forms';
響應(yīng)式表單包含了一組開(kāi)箱即用的常用驗(yàn)證器函數(shù)。這些函數(shù)接收一個(gè)控件,用以驗(yàn)證并根據(jù)驗(yàn)證結(jié)果返回一個(gè)錯(cuò)誤對(duì)象或空值。
Step 2 - 把字段設(shè)為必填
最常見(jiàn)的校驗(yàn)項(xiàng)是把一個(gè)字段設(shè)為必填項(xiàng)。本節(jié)描述如何為 firstName 控件添加“必填項(xiàng)”驗(yàn)證器。
在組件中,把靜態(tài)方法 Validators.required 設(shè)置為 firstName 控件值數(shù)組中的第二項(xiàng)。
profileForm = this.fb.group({
firstName: ['', Validators.required],
lastName: [''],
address: this.fb.group({
street: [''],
city: [''],
state: [''],
zip: ['']
}),
});
HTML5 有一組內(nèi)置的屬性,用來(lái)進(jìn)行原生驗(yàn)證,包括 required、minlength、maxlength等。雖然是可選的,不過(guò)你也可以在表單的輸入元素上把它們添加為附加屬性來(lái)使用它們。這里我們把 required 屬性添加到 firstName輸入元素上。
<input type="text" formControlName="firstName" required>
這些 HTML5 驗(yàn)證器屬性可以和 Angular響應(yīng)式表單提供的內(nèi)置驗(yàn)證器組合使用。組合使用這兩種驗(yàn)證器實(shí)踐,可以防止在模板檢查完之后表達(dá)式再次被修改導(dǎo)致的錯(cuò)誤。
8:顯示表單的狀態(tài)
現(xiàn)在,你已經(jīng)往表單控件上添加了一個(gè)必填字段,它的初始值是無(wú)效的(invalid)。這種無(wú)效狀態(tài)冒泡到其父 FormGroup 中,也讓這個(gè) FormGroup 的狀態(tài)變?yōu)闊o(wú)效的。你可以通過(guò)該 FormGroup 實(shí)例的 status 屬性來(lái)訪(fǎng)問(wèn)其當(dāng)前狀態(tài)。
<p>
Form Status: {{ profileForm.status }}
</p>
9:使用表單數(shù)組管理動(dòng)態(tài)控件
FormArray 是 FormGroup 之外的另一個(gè)選擇,用于管理任意數(shù)量的匿名控件,如果你事先不知道子控件的數(shù)量,F(xiàn)ormArray是一個(gè)很好的選擇
Step 1 - 導(dǎo)入 FormArray
import { FormArray } from '@angular/forms';
Step 2 - 定義 FormArray
為 profileForm 添加一個(gè) aliases 屬性,把它定義為 FormArray 類(lèi)型。(FormBuilder 服務(wù)用于創(chuàng)建 FormArray 實(shí)例。)
profileForm = this.fb.group({
firstName: ['張', Validators.required],
lastName: ['以'],
address: this.fb.group({
street: [''],
city: [''],
state: [''],
zip: ['']
}),
aliases: this.fb.array([
this.fb.control('')
])
});
Step 3 - 訪(fǎng)問(wèn)FormArray控件
通過(guò) getter 來(lái)訪(fǎng)問(wèn)控件比較便捷,也容易復(fù)用
使用 getter 語(yǔ)法來(lái)創(chuàng)建一個(gè)名為 aliases 的類(lèi)屬性
get aliases() {
}
從父控件 FormGroup 中接收綽號(hào)的 FormArray 控件。
get aliases() {
return this.profileForm.get('aliases') as FormArray;
}
addAlias() {
this.aliases.push(this.fb.control(''));
}
Step 3 - 在模板中顯示表單數(shù)組
在模型中定義了 aliases 的 FormArray 之后,你必須把它加入到模板中供用戶(hù)輸入,使用 formArrayName 在這個(gè)
FormArray 和模板之間建立綁定。
<div formArrayName="aliases"> <h3>Aliases</h3> <button (click)="addAlias()">Add Alias</button> <div *ngFor="let address of aliases.controls; let i=index"> <!-- The repeated alias template --> <label> Alias: <input type="text" [formControlName]="i"> </label> </div> </div>
每當(dāng)新的 alias 加進(jìn)來(lái)時(shí),F(xiàn)ormArray 就會(huì)基于這個(gè)索引號(hào)提供它的控件。這將允許你在每次計(jì)算根控件的狀態(tài)和值時(shí)跟蹤每個(gè)控件。
全部代碼
html
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
<label>
First Name:
</label>
<input type="text" formControlName="firstName" required>
<label>
Last Name:
</label>
<input type="text" formControlName="lastName">
<div formGroupName="address">
<h3>Address</h3>
<label>Streel</label>
<input type="text" formControlName="street">
<label>City</label>
<input type="text" formControlName="city">
<label>State</label>
<input type="text" formControlName="state">
<label>Zip Code</label>
<input type="text" formControlName="zip">
</div>
<div formArrayName="aliases">
<h3>Aliases</h3>
<button (click)="addAlias()">Add Alias</button>
<div *ngFor="let address of aliases.controls; let i=index">
<label>Alias</label>
<input type="text" [formControlName]="i" >
</div>
</div>
<button type="submit" [disabled]="!profileForm.valid">Submit</button>
<p>
<button (click)="updateProfile()">Update Profile</button>
</p>
<p>
Form Status: {{ profileForm.status }}
</p>
</form>
js
import { Component, OnInit } from '@angular/core';
import {FormControl, FormGroup, FormBuilder, Validators, FormArray} from '@angular/forms';
@Component({
selector: 'app-profile-editor',
templateUrl: './profile-editor.component.html',
styleUrls: ['./profile-editor.component.css']
})
export class ProfileEditorComponent implements OnInit {
profileForm = this.fb.group({
firstName: ['張', Validators.required],
lastName: ['以'],
address: this.fb.group({
street: [''],
city: [''],
state: [''],
zip: ['']
}),
aliases: this.fb.array([
this.fb.control('')
])
});
constructor(private fb: FormBuilder) {
}
ngOnInit() {
}
onSubmit () {
console.warn(this.profileForm.value);
}
updateProfile() {
this.profileForm.patchValue({
firstName: 'Nancy',
address: {
street: '123 Drew Street'
}
});
}
get aliases () {
return this.profileForm.get('aliases') as FormArray;
}
addAlias() {
this.aliases.push(this.fb.control(''));
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
angular select 默認(rèn)值設(shè)置方法
下面小編就為大家?guī)?lái)一篇angular select 默認(rèn)值設(shè)置方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06
AngularJS ng-repeat指令中使用track by子語(yǔ)句解決重復(fù)數(shù)據(jù)遍歷錯(cuò)誤問(wèn)題
這篇文章主要介紹了AngularJS ng-repeat指令中使用track by子語(yǔ)句解決重復(fù)數(shù)據(jù)遍歷錯(cuò)誤問(wèn)題,結(jié)合實(shí)例形式分析了ng-repeat指令遍歷JavaScript數(shù)組錯(cuò)誤的原因與相關(guān)解決技巧,需要的朋友可以參考下2017-01-01
探討AngularJs中ui.route的簡(jiǎn)單應(yīng)用
這篇文章主要介紹了AngularJs中ui.route的簡(jiǎn)單應(yīng)用,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11
AngularJS 監(jiān)聽(tīng)變量變化的實(shí)現(xiàn)方法
今天小編就為大家分享一篇AngularJS 監(jiān)聽(tīng)變量變化的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
AngularJS select加載數(shù)據(jù)選中默認(rèn)值的方法
下面小編就為大家分享一篇AngularJS select加載數(shù)據(jù)選中默認(rèn)值的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
AngularJS中的過(guò)濾器filter用法完全解析
這篇文章主要介紹了AngularJS中的過(guò)濾器filter用法,包括Angular中一些常用的自帶的過(guò)濾器的列舉以及自定義filter的方法,需要的朋友可以參考下2016-04-04
Angular進(jìn)行簡(jiǎn)單單元測(cè)試的實(shí)現(xiàn)方法實(shí)例
這篇文章主要給大家介紹了關(guān)于Angular進(jìn)行簡(jiǎn)單單元測(cè)試的實(shí)現(xiàn)方法,文中僅用了幾行代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Angular具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Angularjs實(shí)現(xiàn)多個(gè)頁(yè)面共享數(shù)據(jù)的方式
本文給大家介紹使用Angularjs實(shí)現(xiàn)多個(gè)頁(yè)面共享數(shù)據(jù)的方式,通過(guò)定義一個(gè)共享服務(wù)service來(lái)實(shí)現(xiàn)此功能,對(duì)angularjs共享數(shù)據(jù)相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)2016-03-03

