Angular 4.x中表单Reactive Forms详解
Angular4.x中有两种表单:
- Template-DrivenForms-模板驱动式表单(类似于Angular1.x中的表单)
- ReactiveForms(Model-DrivenForms)-响应式表单
Template-DrivenForms(模板驱动表单),我们之前的文章已经介绍过了,了解详细信息,请查看-Angular4.xTemplate-DrivenForms。
Contents
- ngModuleandreactiveforms
- FormControlandFormGroup
- ImplementingourFormGroupmodel
- BindingourFormGroupmodel
- Reactivesubmit
- Reactiveerrorvalidation
- SimplifyingwithFormBuilder
Formbaseandinterface
Formbase
Signup
接下来我们要实现的功能如下:
- 绑定name、email、confirm输入框的值
- 为所有输入框添加表单验证功能
- 显示验证异常信息
- 表单验证失败时,不允许进行表单提交
- 表单提交功能
Userinterface
//signup.interface.ts exportinterfaceUser{ name:string; account:{ email:string; confirm:string; } }
ngModuleandreactiveforms
在我们继续深入介绍reactiveforms表单前,我们必须在@NgModule中导入@angular/forms库中的ReactiveFormsModule:
import{ReactiveFormsModule}from'@angular/forms'; @NgModule({ imports:[ ..., ReactiveFormsModule ], declarations:[...], bootstrap:[...] }) exportclassAppModule{}
友情提示:若使用reactiveforms,则导入ReactiveFormsModule;若使用template-driven表单,则导入FormsModule。
Reactiveapproach
我们将基于上面的定义的基础表单,创建SignupFormComponent:
signup-form.component.ts
import{Component}from'@angular/core'; @Component({ selector:'signup-form', template:`... ` }) exportclassSignupFormComponent{ constructor(){} }
这是一个基础的组件,在我们实现上述功能前,我们需要先介绍FormControl、FormGroup、FormBuilder的概念和使用。
FormControlandFormGroup
我们先来介绍一下FormControl和FormGroup的概念:
1、FormControl-它是一个为单个表单控件提供支持的类,可用于跟踪控件的值和验证状态,此外还提供了一系列公共API。
使用示例:
ngOnInit(){ this.myControl=newFormControl('Semlinker'); }
2、FormGroup-包含是一组FormControl实例,可用于跟踪FormControl组的值和验证状态,此外也提供了一系列公共API。
使用示例:
ngOnInit(){ this.myGroup=newFormGroup({ name:newFormControl('Semlinker'), location:newFormControl('China,CN') }); }
现在我们已经创建了FormControl和FormGroup实例,接下来我们来看一下如何使用:
Name: Location:
注意事项:Template-DrivenForms中介绍的ngModel和name=""属性,已经被移除了。这是一件好事,让我们的模板更简洁。
上面示例中,我们必须使用[formGroup]绑定我们创建的myGroup对象,除此之外还要使用formControlName指令,绑定我们创建的FormControl控件。
此时的表单结构如下:
FormGroup->'myGroup' FormControl->'name' FormControl->'location'
ImplementingourFormGroupmodel
signup.interface.ts
exportinterfaceUser{ 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({...}) exportclassSignupFormComponentimplementsOnInit{ user:FormGroup; ngOnInit(){ this.user=newFormGroup({ name:newFormControl(''), account:newFormGroup({ email:newFormControl(''), confirm:newFormControl('') }) }); } }
如果我们想要设置初始数据,我们可以按照上述示例进行设置。通常情况下,我们通过服务端提供的API接口来获取表单的初始信息。
BindingourFormGroupmodel
现在我们已经实例化了FormGroup模型,是时候绑定到对应的DOM元素上了。具体示例如下:
现在FormGroup与FormControl对象与DOM结构的关联信息如下:
//JavaScriptAPIs FormGroup->'user' FormControl->'name' FormGroup->'account' FormControl->'email' FormControl->'confirm' //DOMbindings formGroup->'user' formControlName->'name' formGroupName->'account' formControlName->'email' formControlName->'confirm'
当使用模板驱动的表单时,为了获取f.value表单的值,我们需要先执行#f="ngForm"的操作。而对于使用响应式的表单,我们可以通过以下方式,方便的获取表单的值:
{{user.value|json}}//{name:'',account:{email:'',confirm:''}}
Reactivesubmit
跟模板驱动的表单一样,我们可以通过ngSubmit输出属性,处理表单的提交逻辑:
...
需要注意的是:我们使用user对象作为onSubmit()方法的参数,这使得我们可以获取表单对象的相关信息,具体处理逻辑如下:
exportclassSignupFormComponent{ user:FormGroup; onSubmit({value,valid}:{value:User,valid:boolean}){ console.log(value,valid); } }
上面代码中,我们使用Objectdestructuring(对象解构)的方式,从user对象中获取value和valid属性的值。其中value的值,就是user.value的值。在实际应用中,我们是不需要传递user参数的:
exportclassSignupFormComponent{ user:FormGroup; onSubmit(){ console.log(this.user.value,this.user.valid); } }
表单的数据绑定方式和提交逻辑已经介绍完了,是该介绍表单实际应用中,一个重要的环节—表单验证。
Reactiveerrorvalidation
接下来我们来为表单添加验证规则,首先我们需要从@angular/forms中导入Validators。具体使用示例如下:
ngOnInit(){ this.user=newFormGroup({ name:newFormControl('',[Validators.required,Validators.minLength(2)]), account:newFormGroup({ email:newFormControl('',Validators.required), confirm:newFormControl('',Validators.required) }) }); }
通过以上示例,我们可以看出,如果表单控制包含多种验证规则,可以使用数组声明多种验证规则。若只包含一种验证规则,直接声明就好。通过这种方式,我们就不需要在模板的输入控件中添加required属性。接下来我们来添加表单验证失败时,不允许进行表单提交功能:
... Signup
那么问题来了,我们要如何获取表单控件的验证信息?我们可以使用模板驱动表单中介绍的方式,具体如下:
{{user.controls.name?.errors|json}}
友情提示:?.prop称为安全导航操作符,用于告诉Angularprop的值可能不存在。
此外我们也可以使用FormGroup对象提供的API,来获取表单控件验证的错误信息:
{{user.get('name').errors|json}}
现在我们来看一下完整的代码:
import{Component,OnInit}from'@angular/core'; import{FormControl,FormGroup,Validators}from'@angular/forms'; import{User}from'./signup.interface'; @Component({ selector:'signup-form', template:`Nameisrequired