Angular Reactive Forms 之相關API走讀

Angular的ReactiveForms的使用教程請參考
Angular 4.x Reactive Formssegmentfault

前言

Angular官網有關ReactiveForms相關api走讀,作下筆記。api

FormControl、FormGroup、FormArray。

使用Angular的ReactiveForms時,咱們須要先了解其三大構件
FormControl、FormGroup、FormArray。數組

AbstractControl

這是FormControl,FormGroup和FormArray的基類。
它提供了全部控件和group控件的一些共同行爲,例如運行驗證器,計算狀態和重置狀態。 它還定義了全部子類之間共同的屬性,如值,有效和髒。 不該該直接實例化。app

class AbstractControl {
    constructor(validator: ValidatorFn, asyncValidator: AsyncValidatorFn)
    validator : ValidatorFn
    asyncValidator : AsyncValidatorFn
    value : any
    parent : FormGroup|FormArray 
    status : string
    valid : boolean
    invalid : boolean
    pending : boolean
    disabled : boolean
    enabled : boolean
    errors : ValidationErrors|
}

經常使用屬性異步

  • value: 控件的值async

  • parent: 可用來獲取父控件ui

  • valid: 控件值有效this

  • invalid: 控件值無效code

  • errors: 錯誤對象,通常可用來存放錯誤信息orm

FormControl和FormControlName

  • FormControl用來跟蹤單個表單控件的值和驗證狀態。

  • FormControlName將現有FormGroup中的FormControl與表單控件元素同步。

//name 是FormGroup中的control屬性名
<input type="text" formControlName="name">
class FormControl extends AbstractControl {
    constructor(formState?: any, validator?: ValidatorFn|ValidatorFn[], asyncValidator?: AsyncValidatorFn|AsyncValidatorFn[])
    setValue(value: any, {onlySelf, emitEvent, emitModelToViewChange, emitViewToModelChange}?: {?: boolean,?: boolean,?: boolean,?: boolean}) : void
    patchValue(value: any, options?: {?: boolean,?: boolean,?: boolean,?: boolean}) : void
    reset(formState?: any, {onlySelf, emitEvent}?: {onlySelf?: boolean,?: boolean}) : void
    registerOnChange(fn: Function) : void
    registerOnDisabledChange(fn: (isDisabled: boolean) => void) : void
}
建立FormControl

直接設置控件值

const ctrl = new FormControl('some value');
console.log(ctrl.value);     // 'some value'

您還能夠在實例化時使用表單狀態對象初始化控件,其中包括值和控件是否禁用。

const ctrl = new FormControl({value: 'n/a', disabled: true});
console.log(ctrl.value);     // 'n/a'
console.log(ctrl.status);   // 'DISABLED'

傳入控件值和驗證器
要將同步驗證器(或同步驗證器數組)與控件一塊兒包含,請將其做爲第二個參數傳遞。 異步驗證器也受支持,但必須分別做爲第三個參數傳遞。

const ctrl = new FormControl('', Validators.required);
console.log(ctrl.value);     // ''
console.log(ctrl.status);   // 'INVALID'

FormGroup和FormGroupName

  • FormGroup:跟蹤一組FormControl實例的值和有效性狀態。若是組中的一個控件無效,則整個組將變爲無效。

  • FormGroupName:將嵌套FormGroup同步到DOM元素。

嵌套formgroup裏的formgroup的綁定

<fieldset formGroupName="address">
class FormGroup extends AbstractControl {
    constructor(controls: {[key: string]: AbstractControl}, validator?: ValidatorFn, asyncValidator?: AsyncValidatorFn)
    controls : {[key: string]: AbstractControl}
    registerControl(name: string, control: AbstractControl) : AbstractControl
    addControl(name: string, control: AbstractControl) : void
    removeControl(name: string) : void
    setControl(name: string, control: AbstractControl) : void
    contains(controlName: string) : boolean
    setValue(value: {[key: string]: any}, {onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}) : void
    patchValue(value: {[key: string]: any}, {onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}) : void
    reset(value?: any, {onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}) : void
    getRawValue() : any
}
建立FormGroup
const form = new FormGroup({
  first: new FormControl('Nancy', Validators.minLength(2)),
  last: new FormControl('Drew'),
});
console.log(form.value);   // {first: 'Nancy', last; 'Drew'}
console.log(form.status);  // 'VALID'

您還能夠將組級驗證器做爲第二個參數或組級異步驗證器做爲第三個參數。 當您要執行考慮多個子控件的值的驗證時,這些將派上用場。

const form = new FormGroup({
  password: new FormControl('', Validators.minLength(2)),
  passwordConfirm: new FormControl('', Validators.minLength(2)),
}, passwordMatchValidator);
function passwordMatchValidator(g: FormGroup) {
   return g.get('password').value === g.get('passwordConfirm').value
      ? null : {'mismatch': true};
}

FormArray和FormArrayName

  • FormArray:跟蹤FormControl,FormGroup或FormArray實例數組的值和有效性狀態。

  • FormArrayName:將嵌套的FormArray同步到DOM元素。
    嵌套formgroup裏的formgroup的綁定

<div formArrayName="formarray">
class FormArray extends AbstractControl {
    constructor(controls: AbstractControl[], validator?: ValidatorFn, asyncValidator?: AsyncValidatorFn)
    controls : AbstractControl[]
    at(index: number) : AbstractControl
    push(control: AbstractControl) : void
    insert(index: number, control: AbstractControl) : void
    removeAt(index: number) : void
    setControl(index: number, control: AbstractControl) : void
    length : number
    setValue(value: any[], {onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}) : void
    patchValue(value: any[], {onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}) : void
    reset(value?: any, {onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}) : void
    getRawValue() : any[]
}
建立FormArray
const arr = new FormArray([
  new FormControl('Nancy', Validators.minLength(2)),
  new FormControl('Drew'),
]);
console.log(arr.value);   // ['Nancy', 'Drew']
console.log(arr.status);  // 'VALID'

您還能夠將第二個arg或數組級異步驗證器做爲第三個參數包含數組級驗證器。 當您要執行考慮多個子控件的值的驗證時,這些將派上用場。

FormGroup和FormArray區別

FormArray是FormGroup的一個變體。 關鍵的區別在於它的數據被序列化爲一個數組(而不是在FormGroup的狀況下被序列化爲一個對象)。 當您不知道組內將出現多少控件(如動態表單)時,這可能會特別有用。要更改數組中的控件,請在FormArray自己中使用push,insert或removeAt方法。 這些方法確保控件在窗體的層次結構中正確跟蹤。

FormBuilder簡化編寫

它基本上是語法糖,縮短了新的FormGroup(),新的FormControl()和新的FormArray()樣板,能夠創建更大的形式。

class FormBuilder {
  
  // 基於controlsConfig、extra信息(添加驗證器),建立FormGroup對象
  group(controlsConfig: {[key: string]: any}, extra: 
      {[key: string]: any} = null): FormGroup {}
  
  // 基於formState、validator、asyncValidator建立FormControl對象
  control(
      formState: Object, validator: ValidatorFn|ValidatorFn[] = null,
      asyncValidator: AsyncValidatorFn|AsyncValidatorFn[] = null): FormControl {}
  
  //基於controlsConfig、validator、asyncValidator建立FormArray對象
  array(
      controlsConfig: any[], validator: ValidatorFn = null,
      asyncValidator: AsyncValidatorFn = null): FormArray {}
}
this.user = this.fb.group({
    name: ['', [Validators.required, Validators.minLength(2)]],
    account: this.fb.group({
      email: ['', Validators.required],
      confirm: ['', Validators.required]
    })
  });

Reactive Forms使用總結

以上介紹FormControl、FormGroup、FormArray的API也僅僅只是介紹其構造方法。使用Reactive Forms,無非最主要的是

  • 構建form對象及其綁定到DOM表單元素

  • 添加驗證器

  • 顯示錯誤

  • 獲取某個控件及其值

  • 監聽數據和狀態變化

構建form對象及其綁定到DOM表單元素、添加驗證器

上述已講

顯示錯誤

表單控件有一些狀態類型屬性,如pristine, dirty, valid,invalid,touched,untouched表示某一種狀態是否爲真。驗證的錯誤信息結果,會放在name.errors裏。

<div [hidden]="userForm.controls.name.valid||userForm.controls.name.pristine">
    <p *ngIf="userForm.controls.name.errors?.minlength">姓名最小長度爲3</p>
    <p *ngIf="userForm.controls.name.errors?.required">必須輸入姓名</p>
</div>

獲取control

formgroup.get('first');  
formgroup.get('name.first')  
this.form.get(['person', 'name']);
formgroup.controls.key

獲取控件值

control.value

設置控件值

AbstractControl.setValue or AbstractControl.patchValue

formgroup.setValue({...}) //設置總體  
formgroup.patchValue({xxx:xxx}) //設置單個control值
const arr = new FormArray([
   new FormControl(),
   new FormControl()
]);
console.log(arr.value);   // [null, null]
arr.patchValue(['Nancy']);
console.log(arr.value);   // ['Nancy', null]

監聽值和狀態

AbstractControl.valueChanges  
AbstractControl.statusChanges

其餘

FormGroupDirective

將現有的FormGroup綁定到DOM元素。那他和FormGroupName有什麼區別?
此僞指令接受頂級FormGroup實例。 而後,它將使用此FormGroup實例將任何子FormControl,FormGroup和FormArray實例與子FormControlName,FormGroupName和FormArrayName指令進行匹配。

<form [formGroup]="form" (ngSubmit)="onSubmit()">

FormControlDirective

將獨立的FormControl實例同步到表單控件元素。

import {Component} from '@angular/core';
import {FormControl, Validators} from '@angular/forms';
@Component({
  selector: 'example-app',
  template: `
     <input [formControl]="control">
     <p>Value: {{ control.value }}</p>
     <p>Validation status: {{ control.status }}</p>
     <button (click)="setValue()">Set value</button>
  `,
})
export class SimpleFormControl {
  control: FormControl = new FormControl('value', Validators.minLength(2));
  setValue() { this.control.setValue('new value'); }
}
相關文章
相關標籤/搜索