官方文档并没有说明
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
都要设置值。