Асинхронный валидатор не работает с формами, управляемыми шаблонами, в Angular

Я создал асинхронный валидатор для моей формы, управляемой шаблоном.

import {Directive, forwardRef} from "@angular/core";
import {NG_ASYNC_VALIDATORS, Validator, AbstractControl, AsyncValidator} from "@angular/forms";
import {Observable} from "rxjs";


@Directive({
  selector: '[asyncValidator][ngModel]',
  providers: [{
    provide: NG_ASYNC_VALIDATORS, useExisting: forwardRef(() => AsyncAgeValidator), multi: true

  }]
})

export class AsyncAgeValidator implements Validator{

  validate(c: AbstractControl): Observable<{[key : number] : any}>{
      return this.validateAgeObservable(c.value);
  }

  validateAgeObservable( age: number ) {
    return new Observable(observer => {

      if( age === 20 ) {
        observer.next(null);
      } else {
        observer.next({asyncInvalid: true});
        console.log('validate');
      }
    });
  }

  }


}

Я использую его в своем шаблоне следующим образом, но я не получаю сообщение об ошибке, которое я ожидаю от валидатора в шаблоне. вызов идет к валидатору, но я предполагаю, что он не регистрирует наблюдаемое в компоненте.

<md-input-container>
  <input mdInput type="number" name="age" [(ngModel)]="user.age" placeholder="Age" required asyncValidator>
</md-input-container>

person Rahul    schedule 18.05.2017    source источник


Ответы (2)


Ваш наблюдаемый никогда не завершается, поэтому Angular не знает, когда изменить статус формы. Так что помните, что ваш наблюдаемый должен завершиться.

Вы можете сделать это разными способами:

1) вручную вызвать метод complete() на наблюдателе:

validateAgeObservable( age: number ) {
  return new Observable(observer => {
    observer.next(age === 20 ? null : {asyncInvalid: true});
    observer.complete();
  });
}

Пример планкера

2) вызвать метод first():

validate(c: AbstractControl): Observable<{[key : number] : any}>{
    return this.validateAgeObservable(c.value).first();
}

validateAgeObservable( age: number ) {
  return new Observable(observer => {
    observer.next(age === 20 ? null : {asyncInvalid: true});
  });
}

Пример планкера

person yurzui    schedule 18.05.2017
comment
Привет ! Вы бы знали ответ на это? stackoverflow.com/ вопросы/44044163/ - person Coder1000; 18.05.2017

Чтобы добавить ко второму ответу Юрзуи:

это работает:

validate(c: AbstractControl): Observable<{[key : number] : any}>{
    return this.validateAgeObservable(c.value).first();
}

так и это:

validate(c: AbstractControl): Observable<{[key : number] : any}>{
    return this.validateAgeObservable(c.value).take(1);
}
person Alberto Millan    schedule 07.05.2018