Angular的ReactiveForms的使用教程请参考
Angular 4.x Reactive Forms
前言
Angular官网有关ReactiveForms相关api走读,做下笔记。
FormControl、FormGroup、FormArray。
使用Angular的ReactiveForms时,我们需要先了解其三大构件
FormControl、FormGroup、FormArray。
AbstractControl
这是FormControl,FormGroup和FormArray的基类。
它提供了所有控件和group控件的一些共同行为,例如运行验证器,计算状态和重置状态。 它还定义了所有子类之间共同的属性,如值,有效和脏。 不应该直接实例化。
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: 控件的值
parent: 可用来获取父控件
valid: 控件值有效
invalid: 控件值无效
errors: 错误对象,一般可用来存放错误信息
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'); }
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。