2017-07-26 9 views
0

私は、キー付きのユーザー名が存在するかどうかを確認するカスタムバリデータを実装しようとしています。しかし、私はコントロールが常に無効な問題に遭遇しています。私はwebApiが正しい値を返していることを確認し、バリデーター関数は適切なreturn文を実行しています。角2カスタムバリデータ(テンプレートフォーム)検証

次のように私のカスタムバリデータは次のとおりです。

import { Directive, forwardRef } from '@angular/core'; 
import { AbstractControl, ValidatorFn, NG_VALIDATORS, Validator, FormControl } from '@angular/forms'; 
import { UsersService } from '../_services/index'; 
import { Users } from '../admin/models/users'; 

function validateUserNameAvailableFactory(userService: UsersService): ValidatorFn { 
    return (async (c: AbstractControl) => { 
     var user: Users; 
     userService.getUserByName(c.value) 
      .do(u => user = u)    
      .subscribe(
      data => { 
       console.log("User " + user) 
       if (user) { 
        console.log("Username was found"); 
        return { 
         usernameAvailable: { 
          valid: false 
         } 
        } 
       } 
       else { 
        console.log("Username was not found"); 
        return null; 
       } 
      }, 
      error => { 
       console.log("Username was not found"); 
       return null; 
      })    

    }) 
} 

@Directive({ 
    selector: '[usernameAvailable][ngModel]', 
    providers: [ 
     { provide: NG_VALIDATORS, useExisting: forwardRef(() => UserNameAvailableValidator), multi: true } 
    ] 
}) 

export class UserNameAvailableValidator implements Validator { 
    validator: ValidatorFn; 

    constructor(private usersService: UsersService) { 

    }  

    ngOnInit() {   
     this.validator = validateUserNameAvailableFactory(this.usersService);   
    } 

    validate(c: FormControl) { 
     console.log(this.validator(c)); 
     return this.validator(c); 
    } 
} 

そして、フォームは次のようになります。

<form #userForm="ngForm" (ngSubmit)="onSubmit()" novalidate> 
     <div class="form form-group col-md-12"> 
     <label for="UserName">User Name</label> 
     <input type="text" class="form-control" id="UserName" 
       required usernameAvailable maxlength="50" 
       name="UserName" [(ngModel)]="user.userName" 
       #UserName="ngModel" /> 
     <div [hidden]="UserName.valid || UserName.pristine" class="alert alert-danger"> 
      <p *ngIf="UserName.errors.required">Username is required</p> 
      <p *ngIf="UserName.errors.usernameAvailable">Username is not available</p> 
      <p *ngIf="UserName.errors.maxlength">Username is too long</p> 
     </div> 
     <!--<div [hidden]="UserName.valid || UserName.pristine" class="alert alert-danger">Username is Required</div>-->   
     </div> 
</form> 

私は、この構造を証明するいくつかのチュートリアルに従ってきた作品なので、私は、私は多分いじり午前と仮定していますバリデータ関数内からの戻り値を返します。

また、エラーリスト(ngForでliを使ってみましたが、何も得られません)を表示する方法はありますか? trueため

+0

https://angular.io/guide/form-validation#custom-validationとhttps://stackoverflow.com/documentation/angular2/6284/angular2-custom-validations#t=201707261704537121485 – JGFMK

答えて

0

リターンは次のようになります。falseため

{usernameAvailable: true}

またはnull

+0

私は周りを遊んでいました私が返品について何かを混乱させたかどうかを見て、それが購読内から価値を返そうとすることとは何かを理解しています。 return文をハードコードしてサービスコールにコメントすると、エラーは適切に設定されます。私は、購読イベントで何が間違っているのかを理解することはできません。 –

1

だから私のように.subscribeを使用すると何か問題がありました。私は、次の2つのリンクを使用して解決策を見つけた:

https://netbasal.com/angular-2-forms-create-async-validator-directive-dd3fd026cb45 http://cuppalabs.github.io/tutorials/how-to-implement-angular2-form-validations/

は今、私のバリデータは次のようになります。これが今取り組んでいる

import { Directive, forwardRef } from '@angular/core'; 
import { AbstractControl, AsyncValidatorFn, ValidatorFn, NG_VALIDATORS, NG_ASYNC_VALIDATORS, Validator, FormControl } from '@angular/forms'; 
import { Observable } from "rxjs/Rx"; 
import { UsersService } from '../_services/index'; 
import { Users } from '../admin/models/users'; 

@Directive({ 
    selector: "[usernameAvailable][ngModel], [usernameAvailable][formControlName]", 
    providers: [ 
     { 
      provide: NG_ASYNC_VALIDATORS, 
      useExisting: forwardRef(() => UserNameAvailableValidator), multi: true 
     } 
    ] 
}) 

export class UserNameAvailableValidator implements Validator { 

    constructor(private usersService: UsersService) { 

    } 

    validate(c: AbstractControl): Promise<{ [key: string]: any }> | Observable<{ [key: string]: any }> { 
     return this.validateUserNameAvailableFactory(c.value); 
    } 

    validateUserNameAvailableFactory(username: string) { 
     return new Promise(resolve => {   
      this.usersService.getUserByName(username) 
       .subscribe(
       data => { 
        resolve({ 
         usernameAvailable: true 
        }) 
       }, 
       error => { 
        resolve(null); 
       }) 
     })   
    } 
} 

。しかし、私は現在、非同期バリデータが実行されている間、コントロールが一時的に無効になる問題があります。

+0

非同期呼び出しが完了するまでフィールドを無効にしておきますか? –

関連する問題