FormControl
maxLength(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
// 给个报错信息
if (control.value === '333') {
return {sex: true};
}
return null;
};
}
sex: FormControl = new FormControl({value: '111', disabled: false}, [this.maxLength()]);
<input type="text" [formControl]="sex">
getError 与hasError
返回类型不一样
getError :any
hasError :boolean
formModel!: FormGroup;
ngOnInit(): void {
this.formModel = new FormGroup({
login: new FormControl('', [this.maxLength()]),
passwords: new FormGroup({
password: new FormControl()
})
});
console.log(this.formModel.getError('sex', ['login']))
}
this.validateForm.getError('required', ['sex'])
this.validateForm.get('sex')!.getError('required')
this.validateForm.getError('required',['loginGroup','add1'])
this.validateForm.getError('required','loginGroup.add1')
getError/hasError
第二个参数可以是一个数组, 进行属性查询
updateValueAndValidity
重新计算控件的值和验证状态。
onlySelf
: 当为true时,只自身被触发但是父级不会被触发。当为false或未提供时,更新所有直接的祖先。默认是false
emitEvent
: 默认为true
,statusChanges
和valueChanges
可观察对象都会在控件更新时发出带有最新状态和值的事件。当为false时,不触发任何事件。
this.form.updateValueAndValidity({emitEvent: false});
get
get(path: Array<string | number> | string): AbstractControl | null;
this.form.get('xxx')!.value
this.form.get(['aaa','bbb'])!.value
this.form.get('aaa.bbb').value // 还可以这样拿值
数组
const g = new FormGroup({'array': new FormArray([new FormControl('111')])});
g.get(['array', 0])!.value
// 111
设置报错信息
setErrors
control.get('timeEnd').setErrors(null);
control.setErrors({required: true});
// 查看报错信息
this.formModel.get('login')!.errors
array-insert
FormArray
数组中,索引插入一个
this.formModel = new FormGroup({
sexArr: new FormArray([])
});
const arr=this.formModel.get('sexArr') as FormArray;
arr.push(new FormControl(1))
arr.push(new FormControl(2))
arr.insert(1,new FormControl(3))
// [1, 3, 2]
插入的时候, 第二个参数也可以添加配置
a.push(c1, {emitEvent: false});
setControl
arr.push(new FormControl(1))
arr.push(new FormControl(2))
arr.setControl(1,new FormControl(4))
// [1,4]
this.formModel.setControl('login',new FormControl('333'))
// {login: '333'}
异步校验器
validatorFnOne = (value: any) => {
console.log(value);
return {controlsOne: true};
};
asyncValidatorFn = (value: any) => of(this.validatorFnOne(value));
this.formModel = new FormGroup({
login: new FormControl('1212', null, this.asyncValidatorFn),
sex1: ['', {
updateOn: 'blur',
validators: [
(val: AbstractControl) => ({sexError: true})
]
}],
});
getRawValue
包括所有的值, 包括禁用的
this.formModel = new FormGroup({
login: new FormControl('111', null, this.asyncValidatorFn),
loginOne: new FormControl('222'),
});
this.formModel?.get('loginOne')!.disable();
console.log(this.formModel.value);
// {login:111}
console.log(this.formModel.getRawValue());
// {login:111,loginOne:222}
reset
a.setValue(['new value', 'new value']);
a.reset([{value: 'initial value', disabled: false}, '']);
a.value
//['initial value', '']
this.validateForm.reset({sex:{value:'2232323',disabled:true}})
reset()
执行,
- 会保留之前的禁用状态
valueChange
和statusChanges
会被执行
pristine
如果用户尚未更改 UI 中的值(默认为true
)
a.pristine //true
a.markAsDirty(); // 触发了, 或者输入改变值
a.pristine // false
a.reset(); // 重置状态
a.pristine // true
dirty
是否更改了 UI 中的值
跟pristine
的值相反(默认是false
)
untouched
如果控件未被标记为已触摸(默认为true
)
我们发现当我们失去焦点才会触发状态的修改blur
或者markAsTouched()
a.untouched //true
a.markAsTouched(); // 触发了, 或者输入改变值
a.untouched // false
a.reset(); // 重置状态
a.untouched // true
touched
如果控件标记为 则为真touched
。
跟untouched
相反
报错的状态
// 默认
g.valid // true
g.errors // null
g.setErrors({required: true}) // 设置报错
g.valid // false
g.errors // {required: true}
pending
这个我还不清楚实用的点
默认为false
校验的状态
markAsPending(opts: { onlySelf?: boolean; emitEvent?: boolean; } = {}): void
c.markAsPending();
c.pending // true
校验
interface AbstractControlOptions {
/**
* @description
* The list of validators applied to a control.
*/
validators?: ValidatorFn | ValidatorFn[] | null;
/**
* @description
* The list of async validators applied to control.
*/
asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null;
/**
* @description
* The event name for control to update upon.
*/
updateOn?: 'change' | 'blur' | 'submit';
}
第二个,第三个
validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null);
status
a.status // VALID
a.disabled // false
a.disable();
a.status // DISABLED
a.disabled // true
a.enable();
a.status // VALID
a.disabled // false
FormBuilder
export class ThreeControlComponent implements OnInit {
validateForm!: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit(): void {
this.validateForm = this.fb.group({
sex: ['111'],
login: [{value: 'xxxxx', disabled: false}, this.validatorFn,this.asyncValidatorFn],
a: this.fb.array([
'one',
['two', this.validatorFn, this.validatorFnOne],
{value: 'three', disabled: false},
[{value: 'four', disabled: false},this.validatorFn, this.validatorFnOne],
this.fb.control('xxx'),
this.fb.control({value:'xxx',disabled:false}),
])
});
}
}
updateOn 更新策略
updateOn:FormHooks
可能的值:'change'| 'blur'| 'submit' 默认值:'change'
案例:
this.validateForm = this.fb.group({
sex1: ['', {updateOn: 'blur'}],
})
// 我们发现失去焦点的时候会触发
this.validateForm.get('sex1')!.valueChanges.subscribe(console.log)
// 查看当前的更新方式
this.validateForm.get('sex1')!.updateOn
// blur
如果有更新策略,那么第二个参数
{
validators:[],
asyncValidators:[],
updateOn:'blur'
}
setValidators/setAsyncValidators
设置校验方式
validatorFnOne = (value: any) => {
// console.log(value);
return {controlsOne: true};
};
asyncValidatorFn = (value: any) => of(this.validatorFnOne(value));
this.validateForm.get('sex1')!.setValidators([Validators.required])
this.validateForm.get('sex1')!.setAsyncValidators([this.asyncValidatorFn]);
dirty
当通过 UI 更改控件的值时,控件会变dirty
, 默认为false
this.validateForm.get('sex1')!.dirty // false
this.validateForm.get('sex1')!.markAsDirty();
this.validateForm.get('sex1')!.dirty // true
windowDuration.invalid && (windowDuration.dirty || windowDuration.touched)
addControl
this.validateForm = this.fb.group({
sex1: ['', {updateOn: 'blur'}],
});
this.validateForm.addControl('two1',new FormControl('1111'),{})
removeControl
this.validateForm.removeControl('sex')
g.removeControl('two', {emitEvent: false});
contains
查看表单是否有这个控件,默认为false
this.validateForm = this.fb.group({
sex: ['111', [Validators.required]],
});
console.log(this.validateForm.contains('sex')); //true
通过dom修改表单的值,触发更新
<form [formGroup]="validateForm">
<input type="text" formControlName="sex" #sex>
</form>
import {ɵgetDOM as getDOM} from '@angular/common';
export class ThreeControlComponent implements OnInit, AfterViewInit {
dispatchEvent(element: any, eventType: any): void {
const evt: Event = getDOM().getDefaultDocument().createEvent('Event');
evt.initEvent(eventType, true, true);
getDOM().dispatchEvent(element, evt);
}
ngAfterViewInit() {
this.sex.nativeElement.value='111111111';
setTimeout(()=>{
this.dispatchEvent(this.sex.nativeElement, 'input');
console.log(this.validateForm.value);
})
}
}
本质是因为DOM的修改,不会触发脏检查, 需要通过自定义事件进行触发脏检查机制, 从而更新
form表单完整版本
<form [formGroup]="validateForm">
<input type="text" formControlName="sex">
<!-- 对象集合-->
<ng-container formGroupName="sexGroup">
<input type="text" formControlName="sexOne">
</ng-container>
<!-- 数组集合-->
<ng-container formArrayName="sexArr">
<ng-container *ngFor="let item of sexArrControl.controls;let index=index">
<ng-container [formGroupName]="index">
<input type="text" formControlName="sexOne">
<input type="text" formControlName="sexTwo">
</ng-container>
</ng-container>
</ng-container>
</form>
export class ThreeControlComponent implements OnInit, AfterViewInit, AfterContentInit {
validateForm!: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit(): void {
this.validateForm = this.fb.group({
sex: ['111'],
sexGroup: this.fb.group({
sexOne: ['222']
}),
sexArr: this.fb.array([])
});
this.sexArrControl.push(this.sexObj)
}
get sexObj(): FormGroup {
return this.fb.group({
sexOne: ['a'],
sexTwo: ['b'],
})
}
get sexArrControl(): FormArray {
return this.validateForm.get('sexArr') as FormArray;
}
}