2017-02-21 101 views
3

當我有什麼在customerNameValidator返回如果什麼在角2異步驗證器可以通過觀測

異步驗證失敗/成功,我的「客戶名稱」 FormControl是無效的回報?

this.customerForm = this.formBuilder.group({ 
customerName: 
[this.newCustomerName, [Validators.minLength(2), Validators.required],[this.customerNameValidator.bind(this)]] 
}); 


customerNameValidator(c: AbstractControl) 
{ 
    return this.service.customerExists(c.value,this.companyId).subscribe(response => 
    { 
     if(response == true) 
     { 
      alert("true"); 
     } 
     else 
     { 
      alert("false"); 
     } 
    }); 
} 
+0

一個observable發出與驗證器返回的內容相同的內容:如果沒有錯誤,則返回null,如果有錯誤,則返回帶有錯誤鍵的對象。 –

回答

6

您不應該訂閱,而應該映射observable以更改返回流的結果,而不是從中讀取。

customerNameValidator(c: AbstractControl) 
{ 
    return this.service.customerExists(c.value,this.companyId).map(response => 
    { 
     if(response == true) 
     { 
      return { customerExists: true }; 
     } 
     else 
     { 
      return; 
     } 
    }); 
} 

返回一個值爲true的對象是您應如何返回observable。儘管你可能會遺漏一些重要的異步驗證器步驟,但由於我們沒有給出所有代碼,所以很難說。 Try checking out this articlethis article瞭解更多信息。

+1

謝謝你的工作! – Elisabeth

+0

只是想知道新的自定義驗證器類將如何實現在FormBuilder中的異步驗證?謝謝 –

+0

@HungBui與其他自定義驗證器類相同的方式將被實現。你的驗證器應該是一個傳入表單控件的函數。 https://blog.thoughtram.io/angular/2016/03/14/custom-validators-in-angular-2.html – Adam

3

我使用角度爲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。