我使用角度为4.1.2的AsyncValidatorFn实现了一个被动式窗体。并想分享一些我的学习
我发现角度不会(自动)更新AsyncValidatorFn的窗体控件,因为它为内部同步验证程序。
左右,具体根据“AsyncValidatorFn”接口规范,你有你的实现
(c: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>;
,然后为“手动”更新您的表单控件,您将检查在html元素
控制状态
果然不出我所实现的是一个用户名存在,检查可能会很常用在用户注册过程中发现以下
是代码摘录:
形式控制
// Supports alphabets and numbers no special characters except underscore('_') and dash('-') min 3 and max 20 characters.
this.userName = new FormControl('', Validators.compose([Validators.required, Validators.pattern('^[A-Za-z0-9_-]{3,20}$')]),Validators.composeAsync([this.checkUser()]));
自定义异步验证器和辅助功能
checkUser(): AsyncValidatorFn{
return (c: AbstractControl): Observable<ValidationErrors> => {
return c
.valueChanges
.debounceTime(400)
.mergeMap(value => this.gabriel.filter({'userName':value}))
.map(stat => this.mapErr(c, stat));
}
}
private mapErr(c: AbstractControl, res: any): ValidationErrors{
let err: ValidationErrors;
switch (res['state']){
case 0:
err = null;
break;
case -100:
err = {'existed': true};
break;
case -1:
default:
err = {'failed': true};
}
c.setErrors(err);
return err;
}
注意,我输入的控制作为参数进入“mapErr”功能,并设置由“c中的控制.setErrors(ERR);”。
“return err;”语句根据“AsyncValidatorFn”接口规范返回“ValidationErrors”。
“gabriel.filter()”用提取的用户名查询后端;并返回0,-100,-1分别 “OK”, “复制” 和 “操作失败”
filter(json): Observable<{}>{
let body = JSON.stringify(json);
let headers = new Headers({'Content-Type': 'application/json'});
let options = new RequestOptions({ headers: headers });
return this.http.post(Cons.filter, body, options).timeout(10000).map((res:Response) => res.json());
}
控制在HTML文件中检查
<form [formGroup]="sf" (ngSubmit)="signin()">
<ion-item>
<ion-label>UserName</ion-label>
<ion-input type="text" formControlName="userName" [class.invalid]="userName.dirty&&userName.invalid&&userName.errors!=null" ></ion-input>
</ion-item>
<p *ngIf="userName.dirty && userName.hasError('existed')">
Username already existed
</p>
<p *ngIf="userName.dirty && userName.hasError('failed')">
can not check validity of Username
</p>
<ion-item>
我还发现了在同步验证器在一个表单控件中得到满足之前,异步验证器不会被触发。
在我的情况
,我还使用了内置Validators.pattern定义的3的最小长度(参见上述用户名formControl定义)
自定义异步验证器从未只要我的输入长度是触发短于3。
一个observable发出与验证器返回的内容相同的内容:如果没有错误,则返回null,如果有错误,则返回带有错误键的对象。 –