Angular 4.x 中有两种表单:
Template-Driven Forms - 模板驱动式表单 (类似于 Angular 1.x 中的表单 )
Reactive Forms (Model-Driven Forms) - 响应式表单
Template-Driven Forms (模板驱动表单) ,我们之前的文章已经介绍过了,了解详细信息,请查看 - Angular 4.x Template-Driven Forms 。
Contents
ngModule and reactive forms
FormControl and FormGroup
Implementing our FormGroup model
Binding our FormGroup model
Reactive submit
Reactive error validation
Simplifying with FormBuilder
Form base and interface
Form base
<form novalidate> <label> <span>Full name</span> <input type="text" placeholder="Your full name"> </label> <div> <label> <span>Email address</span> <input type="email" placeholder="Your email address"> </label> <label> <span>Confirm address</span> <input type="email" placeholder="Confirm your email address"> </label> </div> <button type="submit">Sign up</button> </form>
接下来我们要实现的功能如下:
绑定 name、email、confirm 输入框的值
为所有输入框添加表单验证功能
显示验证异常信息
表单验证失败时,不允许进行表单提交
表单提交功能
User interface
// signup.interface.ts export interface User { name: string; account: { email: string; confirm: string; } }
ngModule and reactive forms
在我们继续深入介绍 reactive forms 表单前,我们必须在 @NgModule 中导入 @angular/forms 库中的 ReactiveFormsModule:
import { ReactiveFormsModule } from '@angular/forms'; @NgModule({ imports: [ ..., ReactiveFormsModule ], declarations: [...], bootstrap: [...] }) export class AppModule {}
友情提示:若使用 reactive forms,则导入 ReactiveFormsModule;若使用 template-driven 表单,则导入 FormsModule。
Reactive approach
我们将基于上面的定义的基础表单,创建 SignupFormComponent :
signup-form.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'signup-form', template: ` <form novalidate>...</form> ` }) export class SignupFormComponent { constructor() {} }
这是一个基础的组件,在我们实现上述功能前,我们需要先介绍 FormControl、FormGroup、FormBuilder 的概念和使用。
FormControl and FormGroup
我们先来介绍一下 FormControl 和 FormGroup 的概念:
1、FormControl - 它是一个为单个表单控件提供支持的类,可用于跟踪控件的值和验证状态,此外还提供了一系列公共API。
使用示例:
ngOnInit() { this.myControl = new FormControl('Semlinker'); }
2、FormGroup - 包含是一组 FormControl 实例,可用于跟踪 FormControl 组的值和验证状态,此外也提供了一系列公共API。
使用示例:
ngOnInit() { this.myGroup = new FormGroup({ name: new FormControl('Semlinker'), location: new FormControl('China, CN') }); }
现在我们已经创建了 FormControl 和 FormGroup 实例,接下来我们来看一下如何使用:
<form novalidate [formGroup]="myGroup"> Name: <input type="text" formControlName="name"> Location: <input type="text" formControlName="location"> </form>
注意事项:Template-Driven Forms 中介绍的 ngModel 和 属性,已经被移除了。这是一件好事,让我们的模板更简洁。
上面示例中,我们必须使用 [formGroup] 绑定我们创建的 myGroup 对象,除此之外还要使用 formControlName 指令,绑定我们创建的 FormControl 控件。
此时的表单结构如下:
FormGroup -> 'myGroup' FormControl -> 'name' FormControl -> 'location'
Implementing our FormGroup model
signup.interface.ts
export interface User { name: string; account: { email: string; confirm: string; } }
与之对应的表单结构如下:
FormGroup -> 'user' FormControl -> 'name' FormGroup -> 'account' FormControl -> 'email' FormControl -> 'confirm'
是的,我们可以创建嵌套的 FormGroup 集合!让我们更新一下组件 (不包含初始数据):
import { Component, OnInit } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; @Component({...}) export class SignupFormComponent implements OnInit { user: FormGroup; ngOnInit() { this.user = new FormGroup({ name: new FormControl(''), account: new FormGroup({ email: new FormControl(''), confirm: new FormControl('') }) }); } }
如果我们想要设置初始数据,我们可以按照上述示例进行设置。通常情况下,我们通过服务端提供的 API 接口来获取表单的初始信息。
Binding our FormGroup model
现在我们已经实例化了 FormGroup 模型,是时候绑定到对应的 DOM 元素上了。具体示例如下: