在angular中,提供了两种建立表单的方式:css
- 模板驱动型表单(Template Driven Forms)
- 响应式表单(Reactive Forms)
在模板驱动型表单中,咱们直接经过 ngModel 指令在组件模板中建立 control 和绑定数据,不用建立控件、表单对象或编写代码来处理组件类和模板之间的数据交流;而且,咱们不会把表单验证写在组件类中。html
在响应式表单中,咱们在组件类中建立表单对象,并将其绑定到模板中的响应式表单控件中。全部的表单控件和数据验证都写在组件类中;表单验证和表单状态变化是异步的,咱们能够在组件类写代码中观察到这一点。响应式表单一般用于数据模型肯定的情形。react
那么这两种建立表单的方式主要区别在哪里呢?typescript
在响应式表单中,咱们不须要用到ngModel,required等指令,咱们在组件类中建立全部的控件和验证器。它很容易测试和维护。接下来,我将经过FormControl/FormGroup/FormBuilder/FormArray和添加一些表单验证功能来建立一个响应式表单。json
import {ReactiveFormsModule} from '@angular/forms'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, ReactiveFormsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
咱们须要先在组件类中引入 FormGroup, FormControl, FormArray类,这些都是帮助咱们建立响应式表单的神兵利器。bootstrap
import { Component } from '@angular/core'; import { FormGroup, FormControl, FormArray } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'Reactive Forms Demo'; }
FormControl类对应一个单独的表单控件,跟踪它的值和有效性。当咱们建立表单时,咱们会建立一个FormControl的对象。以下:咱们在组件类中建立了一个FormControl对象;app
export class AppComponent { email = new FormControl(''); }
在模板中,咱们经过属性绑定将email表单控件绑定到input元素上。less
<input [formControl]='email' type="text" placeholder="Enter Email"/> {{email.value | json}}
FormGroup是多个FormControl的集合,提供了一个追踪一组表单控件的值或是验证的API。它做为表单视图层的最高级,咱们能够将FormGroup做为一个单独的对象,而后每一个form control都看做是它的一个属性。建立一个FormGroup,以下:异步
loginForm = new FormGroup({ email: new FormControl(' '), password: new FormControl(' ') })
在这里咱们建立了一个登录表单,它有两个表单控件:email和password。对应的视图为:ide
<form [formGroup]='loginForm' novalidate class="form"> <input formControlName='email' type="text" class="form-control" placeholder="Enter Email" /> <input formControlName='password' type="password" class="form-control" placeholder="Enter Password" /> </form> {{loginForm.value | json}} {{loginForm.status | json }}
这里,咱们采用了属性绑定将formcontrolName指令和组件类中的formControl绑定起来。若是你曾经用过模板驱动型表单,会发现这没有ngModel或是name绑定到元素上。咱们还能够直接经过值和状态属性来查看表单的值和状态。
若是要提交表单,咱们须要增长一个提交按纽,而且绑定提交处理函数;以下:
<form (ngSubmit)='loginUser()' [formGroup]='loginForm' novalidate class="form"> <input formControlName='email' type="text" class="form-control" placeholder="Enter Email" /> <input formControlName='password' type="password" class="form-control" placeholder="Enter Password" /> <button class="btn btn-default">Login</button> </form>
在组件类中,添加表单提交处理函数loginUser():
export class AppComponent implements OnInit { loginForm: FormGroup; ngOnInit() { this.loginForm = new FormGroup({ email: new FormControl(null, Validators.required), password: new FormControl() }); } loginUser() { console.log(this.loginForm.status); console.log(this.loginForm.value); } }
要添加表单验证,需先引入angular/forms中的Validators,以下:
ngOnInit() { this.loginForm = new FormGroup({ email: new FormControl(null, Validators.required), password: new FormControl(null, [Validators.required, Validators.maxLength(8)]) }); }
在模板中,咱们经过FormGroup发现某个control的错误,在下面,咱们检查表单验证结果而且用隐藏的div显示错误。以下:
<div class="container"> <br /> <form (ngSubmit)='loginUser()' [formGroup]='loginForm' novalidate class="form"> <input formControlName='email' type="text" class="form-control" placeholder="Enter Email" /> <div class="alert alert-danger" *ngIf="loginForm.get('email').hasError('required') && loginForm.get('email').touched"> Email is required </div> <input formControlName='password' type="password" class="form-control" placeholder="Enter Password" /> <div class="alert alert-danger" *ngIf=" !loginForm.get('password').valid && loginForm.get('email').touched"> Password is required and should less than 10 characters </div> <button [disabled]='loginForm.invalid' class="btn btn-default">Login</button> </form> </div>
FormBuilder 用来简化FormGroup和FormControl之间的语法。当表单特别长的时候,这个类尤为有效。注入进组件中,以下:
constructor(private fb : FormBuilder){}
用它建立响应式表单以下:
this.loginForm = this.fb.group({ email: [null, [Validators.required, Validators.minLength(4)]], password: [null, [Validators.required, Validators.maxLength(8)]] })
组件类中的全部代码以下:
import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, FormArray, Validators, FormBuilder } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { loginForm: FormGroup; constructor(private fb: FormBuilder) { } ngOnInit() { this.loginForm = this.fb.group({ email: [null, [Validators.required, Validators.minLength(4)]], password: [null, [Validators.required, Validators.maxLength(8)]] }) } loginUser() { console.log(this.loginForm.status); console.log(this.loginForm.value); } }
建立响应式表单主要用到FormControl/FormGroup/FormBuilder/FormArray这几类,同时须要先引入响应式表单模块:ReactiveFormsModule。上面几个类之间的关系为:
参考:https://dzone.com/articles/how-to-create-reactive-forms-in-angular