官方文件並沒有說明
Template-driven Form
與Reactive Form
哪一個更好。由於之前開發過一個Ionic2
專案,使用的是Template-driven Form
,光是校驗就有一坨程式碼,維護與開發簡直慘不忍睹,所以個人更加推薦使用Reactive Form
。
使用Reactive Form
(同步),我們會在程式碼中建立整個表單 form control
樹。我們可以立即更新一個值或者深入到表單中的任意節點,因為所有的 Form control
都始終是可用的。而且因為是同步,有利於單元測試。
在Template-driven Form
(非同步)中,我們是通過指令來建立 form control
的。我們在操作一個Form control
之前,必須要經歷一個變化檢測週期。
FormControl、FormGroup、FormArray
FormControl是最小單位(C),FormGroup類似於一個由FormControl(C)元件的object
物件(G),FormArray(A)是一個由FormGroup(G)的Array
陣列。它們之間可以互相巢狀,以應對各式各樣的表單模型(Form Model)。
addForm: FormGroup;
constructor(public formBuilder: FormBuilder) {
this.orderForm = this.formBuilder.group({
name: ['', [Validators.required]],
description: ['', [Validators.required]],
other: this.formBuilder.group({
name: ['', [Validators.required]],
description: ['', [Validators.required]]
}),
items: this.formBuilder.array([
this.formBuilder.group({
name: ['', [Validators.required]],
description: ['', [Validators.required]],
}),
this.formBuilder.group({
name: ['', [Validators.required]],
description: ['', [Validators.required]],
}),
this.formBuilder.group({
name: ['', [Validators.required]],
description: ['', [Validators.required]],
})
])
});
}
複製程式碼
通過this.addForm.value
獲取的值:
{
name:'',
description:'',
other: {
name:'',
description:'',
},
items: [
{
name:'',
description:'',
},
{
name:'',
description:'',
},
{
name:'',
description:'',
}
]
}
複製程式碼
它們三者之間的關係如下:
formGroup =
{
formControlName:formControl,
formControlName:formControl,
formControlName:formControl,
}
formArray = [
formGroup,
formGroup,
]= [
{
formControlName:formControl,
formControlName:formControl,
formControlName:formControl,
},
{
formControlName:formControl,
formControlName:formControl,
formControlName:formControl,
}
]
複製程式碼
對於使用Reactive Form
時,動態增加formControl
也是很方便的。這種在,比如新增出差明細等情況下很適合。
程式碼示例參考
data model與form model
來自伺服器就是資料模型(data model),而FormControl的結構就是表單模型(form model)。
元件必須把資料模型中的英雄值複製到表單模型中。這裡隱含著兩個非常重要的點。
- 開發人員必須理解資料模型是如何對映到表單模型中的屬性的。
- 使用者修改時的資料流是從DOM元素流向表單模型的,而不是資料模型。表單控制元件永遠不會修改資料模型。
個人經驗:
- 按照如此的劃分,從來可以不依賴後端的資料結構(畢竟後端的資料格式是千奇百怪的)。
- 表單模型最好和要提交的資料格式一樣,資料的修改都是操作表單模型的
formControl
。提交的時候不需要手動組裝資料。 - 由於之前的專案使用的是
Template-driven Form
,需要手動組裝提交的資料,而且並沒有嚴格區分資料模型與表單模型,後期維護時,程式碼很亂。 - 儘量使用型別系統,不要圖方便使用
any
,不然維護的時候,這酸爽!!!
setValue 與 patchValue
setValue
: 使用的時候需要每個from control
都要設定值。否則,ERROR Error: Must supply a value for form control with name: 'xxxxx'
patchValue
: 類似打補丁,不需要每個from control
都要設定值。