文章轉(zhuǎn)自我的語雀:https://www.yuque.com/liuyin-zzwa0/angular/reactive-forms
響應(yīng)式表單使用顯式的驮肉、不可變的方式熏矿,管理表單在特定的時(shí)間點(diǎn)上的狀態(tài)。對表單狀態(tài)的每一次變更都會返回一個(gè)新的狀態(tài)离钝,這樣可以在變化時(shí)維護(hù)模型的整體性票编。響應(yīng)式表單是圍繞 Observable 的流構(gòu)建的,表單的輸入和值都是通過這些輸入值組成的流來提供的卵渴,它可以同步訪問慧域。
響應(yīng)式表單還提供了一種更直觀的測試路徑,因?yàn)樵谡埱髸r(shí)你可以確信這些數(shù)據(jù)是一致的浪读、可預(yù)料的昔榴。這個(gè)流的任何一個(gè)消費(fèi)者都可以安全地操縱這些數(shù)據(jù)。
響應(yīng)式表單與模板驅(qū)動的表單有著顯著的不同點(diǎn)碘橘。響應(yīng)式表單通過對數(shù)據(jù)模型的同步訪問提供了更多的可預(yù)測性互订,使用 Observable 的操作符提供了不可變性,并且通過 Observable 流提供了變化追蹤功能蛹屿。
合理使用Angular響應(yīng)式表單屁奏,將使我們更能簡單的實(shí)現(xiàn)一個(gè)復(fù)雜的表單
表單的兩種創(chuàng)建方式
手動創(chuàng)建實(shí)例
直接使用FormGroup與FormControl創(chuàng)建
this.profileForm = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
address: new FormGroup({
street: new FormControl(''),
city: new FormControl(''),
state: new FormControl(''),
zip: new FormControl('')
})
});
使用表單構(gòu)建器
使用FormBuilder服務(wù)創(chuàng)建
this.profileForm = this.fb.group({
firstName: [''],
lastName: [''],
address: this.fb.group({
street: [''],
city: [''],
state: [''],
zip: ['']
}),
});
Tips:當(dāng)然,兩種方式混合使用也是沒問題的
優(yōu)雅的使用響應(yīng)式表單
合理使用 formState
错负、 disable
坟瓢、 enable
勇边、 registerControl
實(shí)現(xiàn)控件的禁用/編輯狀態(tài)
雖然在Angular的類型定義中 formState
為 any
類型,但在實(shí)際的使用中折联,它的類型如下:
interface FormState { value: any; disabled: boolean; }
在構(gòu)建表單時(shí)粒褒,若是有需要某個(gè)字段disabled,下面的方式就可以幫你實(shí)現(xiàn):
this.profileForm = this.fb.group({
firstName: [{value: null, disabled: true}],
});
// 或者诚镰,兩種方式都是一樣的效果
this.profileForm = new FormGroup({
firstName: new FormControl({value: null, disabled: true}),
});
在表單使用中奕坟,動態(tài)enable/disable,這時(shí)候就需要借助FormGroup清笨、FormControl實(shí)現(xiàn)了:
this.profileForm.disable();
this.profileForm.enable();
this.profileForm.get('firstName').disable();
this.profileForm.get('firstName').reset({value: 'Outh', disabled: false});
this.profileForm.reset({
firstName: {value: null, disabled: true},
lastName: {value: 'Jim', disabled: false},
address: {
street: null,
city: null,
state: null,
zip: null
},
});
使用 addControl
月杉、 removeControl
、 FormArray
動態(tài)刪減表單控件
使用方式如下:
this.profileForm.addControl('aliases', this.fb.array([
this.fb.control('')
]));
this.profileForm.removeControl('lastName');
const aliasesArray = (this.profileForm.get('aliases') as FormArray);
aliasesArray.push(this.fb.control(''));
aliasesArray.removeAt(1);
aliasesArray.reset();
template配合響應(yīng)式表單
控件有禁用/編輯狀態(tài)
<div *ngIf="profileForm.get('firstName')?.enabled">
<input formControlName="firstName" />
</div>
動態(tài)的表單控件
<div *ngIf="profileForm.get('firstName')">
<input formControlName="firstName" />
</div>
Tips:若是控件名稱位置抠艾,可以使用
Object.keys
方法實(shí)現(xiàn)
表單數(shù)組展示
<form nz-form [formGroup]="profileForm" nzLayout="horizontal">
<div formArrayName="aliases">
<ng-container *ngFor="let g of profileForm.get('aliases')?.controls; let i= index" [formGroupName]="i">
<nz-form-item>
<nz-form-label nzFor="name" nzSpan="6" nzRequired>name</nz-form-label>
<nz-form-control nzSpan="18">
<input nz-input formControlName="name" id="name" name="name" placeholder="">
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzFor="image" nzSpan="6" nzRequired>image</nz-form-label>
<nz-form-control nzSpan="18">
<input nz-input formControlName="image" id="image" name="image" placeholder="">
</nz-form-control>
</nz-form-item>
</ng-container>
</div>
</form>
基于業(yè)務(wù)對象模型的元數(shù)據(jù)苛萎,動態(tài)創(chuàng)建表單
關(guān)于動態(tài)表單,官方文檔以詳細(xì)列出使用方式了检号,具體請看https://angular.cn/guide/dynamic-form
更多詳細(xì)用法請?jiān)L問響應(yīng)式表單腌歉,推薦使用Angular CLI搭建本地開發(fā)環(huán)境,自行體驗(yàn)O_o