我使用角度爲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,如果有錯誤,則返回帶有錯誤鍵的對象。 –