Angular 4.x 中有两种表单:
-
Template-Driven Forms - 模板驱动式表单 (类似于 AngularJS 1.x 中的表单 ) 官方文档:https://v2.angular.cn/docs/ts/latest/guide/forms.html
-
Reactive Forms (Model-Driven Forms) - 响应式表单 官方文档: https://v2.angular.cn/docs/ts/latest/guide/reactive-forms.html
Template-Driven Forms (模板驱动表单) 的特点
-
使用方便
-
适用于简单的场景
-
通过 [(ngModel)] 实现数据双向绑定
-
最小化组件类的代码
-
不易于单元测试
- 异步的,模板驱动表单会委托指令来创建它们的表单控件。 为了消除“检查完后又变化了”的错误,这些指令需要消耗一个以上的变更检测周期来构建整个控件树。 这意味着在从组件类中操纵任何控件之前,我们都必须先等待一个节拍。
Reactive Forms (响应式表单) 的特点
-
比较灵活
-
适用于复杂的场景
-
简化了HTML模板的代码,把验证逻辑抽离到组件类中
-
方便的跟踪表单控件值的变化
-
易于单元测试
- 同步的 ,使用响应式表单,我们会在代码中创建整个表单控件树。 我们可以立即更新一个值或者深入到表单中的任意节点,因为所有的控件都始终是可用的。
使用reactive forms 表单前,我们必须在@NgModule
中导入@angular/forms
库中的ReactiveFormsModule
:
imports: [
...,ReactiveFormsModule
],declarations: [...],bootstrap: [...]
})
export <span style="color: #0000ff">class AppModule {}
FormControl 和 FormGroup
FormControl - 它是一个为单个表单控件提供支持的类,可用于跟踪控件的值和验证状态,此外还提供了一系列公共API。
使用示例:
FormGroup - 包含是一组 FormControl 实例,可用于跟踪 FormControl 组的值和验证状态,此外也提供了一系列公共API。
使用示例:
现在我们已经创建了FormControl
和FormGroup
实例,接下来我们来看一下如何使用:
ngModel和name=""
属性,已经被移除了。这是一件好事,让我们的模板更简洁。
上面示例中,我们必须使用[formGroup]
绑定我们创建的myGroup
对象,除此之外还要使用formControlName
指令,绑定我们创建的FormControl
控件。此时的表单结构如下:
signup.interface.ts
与之对应的表单结构如下:
是的,我们可以创建嵌套的 FormGroup 集合!让我们更新一下组件 (不包含初始数据):
export <span style="color: #0000ff">class<span style="color: #000000"> SignupFormComponent implements OnInit {
user: FormGroup;
ngOnInit() {
<span style="color: #0000ff">this.user = <span style="color: #0000ff">new<span style="color: #000000"> FormGroup({
name: <span style="color: #0000ff">new FormControl(<span style="color: #800000">''<span style="color: #000000">),account: <span style="color: #0000ff">new<span style="color: #000000"> FormGroup({
email: <span style="color: #0000ff">new FormControl(<span style="color: #800000">''<span style="color: #000000">),confirm: <span style="color: #0000ff">new FormControl(<span style="color: #800000">''<span style="color: #000000">)
})
});
}
}
如果我们想要设置初始数据,我们可以按照上述示例进行设置。通常情况下,我们通过服务端提供的 API 接口来获取表单的初始信息。
绑定FormGroup模型
现在FormGroup
与FormControl
对象与 DOM 结构的关联信息如下:
<span style="color: #008000">//
<span style="color: #008000"> DOM bindingsformGroup -> <span style="color: #800000">'<span style="color: #800000">user<span style="color: #800000">'<span style="color: #000000">
formControlName -> <span style="color: #800000">'<span style="color: #800000">name<span style="color: #800000">'<span style="color: #000000">
formGroupName -> <span style="color: #800000">'<span style="color: #800000">account<span style="color: #800000">'<span style="color: #000000">
formControlName -> <span style="color: #800000">'<span style="color: #800000">email<span style="color: #800000">'<span style="color: #000000">
formControlName -> <span style="color: #800000">'<span style="color: #800000">confirm<span style="color: #800000">'
当使用模板驱动的表单时,为了获取f.value
表单的值,我们需要先执行#f="ngForm"
的操作。而对于使用响应式的表单,我们可以通过以下方式,方便的获取表单的值:
跟模板驱动的表单一样,我们可以通过ngSubmit
输出属性,处理表单的提交逻辑:
需要注意的是,我们使用user
对象作为onSubmit()
方法的参数,这使得我们可以获取表单对象的相关信息,具体处理逻辑如下:
上面代码中,我们使用Object destructuring
(对象解构) 的方式,从user
对象中获取value
和valid
属性的值。其中value
的值,就是user.value
的值。在实际应用中,我们是不需要传递user
参数的:
表单的数据绑定方式和提交逻辑已经介绍完了,是该介绍表单实际应用中,一个重要的环节 — 表单验证。
接下来我们来为表单添加验证规则,首先我们需要从@angular/forms
中导入Validators
。具体使用示例如下:
通过以上示例,我们可以看出,如果表单控制包含多种验证规则,可以使用数组声明多种验证规则。若只包含一种验证规则,直接声明就好。通过这种方式,我们就不需要在模板的输入控件中添加required
属性。接下来我们来添加表单验证失败时,不允许进行表单提交功能:
那么问题来了,我们要如何获取表单控件的验证信息?我们可以使用模板驱动表单中介绍的方式,具体如下:
此外我们也可以使用FormGroup
对象提供的 API,来获取表单控件验证的错误信息:
完整代码: