Angular的ReactiveForms的使用教程请参考
Angular 4.x Reactive Formssegmentfault
Angular官网有关ReactiveForms相关api走读,作下笔记。api
使用Angular的ReactiveForms时,咱们须要先了解其三大构件
FormControl、FormGroup、FormArray。数组
这是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将现有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 }
直接设置控件值
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:跟踪一组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 }
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:跟踪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[] }
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或数组级异步验证器做为第三个参数包含数组级验证器。 当您要执行考虑多个子控件的值的验证时,这些将派上用场。
FormArray是FormGroup的一个变体。 关键的区别在于它的数据被序列化为一个数组(而不是在FormGroup的状况下被序列化为一个对象)。 当您不知道组内将出现多少控件(如动态表单)时,这可能会特别有用。要更改数组中的控件,请在FormArray自己中使用push,insert或removeAt方法。 这些方法确保控件在窗体的层次结构中正确跟踪。
它基本上是语法糖,缩短了新的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] }) });
以上介绍FormControl、FormGroup、FormArray的API也仅仅只是介绍其构造方法。使用Reactive Forms,无非最主要的是
构建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>
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
将现有的FormGroup绑定到DOM元素。那他和FormGroupName有什么区别?
此伪指令接受顶级FormGroup实例。 而后,它将使用此FormGroup实例将任何子FormControl,FormGroup和FormArray实例与子FormControlName,FormGroupName和FormArrayName指令进行匹配。
<form [formGroup]="form" (ngSubmit)="onSubmit()">
将独立的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'); } }