在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