异步验证器不适用于 Angular 中的模板驱动表单

Posted

技术标签:

【中文标题】异步验证器不适用于 Angular 中的模板驱动表单【英文标题】:Async Validator not working with Template driven Forms in Angular 【发布时间】:2017-10-18 01:31:52 【问题描述】:

我为我的模板驱动表单创建了一个异步验证器。

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>

【问题讨论】:

【参考方案1】:

添加到 yurzui 的第二个答案:

这行得通:

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);

【讨论】:

【参考方案2】:

您的 observable 永远不会完成,因此 Angular 不知道何时更改表单状态。所以记住你的 observable 必须完成。

您可以通过多种方式实现此目的:

1) 在观察者上手动调用complete() 方法:

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

Plunker Example

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);
  );

Plunker Example

【讨论】:

您好!你知道这个问题的答案吗? ***.com/questions/44044163/…

以上是关于异步验证器不适用于 Angular 中的模板驱动表单的主要内容,如果未能解决你的问题,请参考以下文章

表单验证不适用于 Ionic 2 中的 Angular 2 FormBuilder

Angular - 模板驱动的表单 - 控制器中的自定义验证器功能

如何通过模板驱动形式验证 Angular 7 中的下拉列表

Angular/Rxjs 管道异步不适用于 s-s-r?

通过 Angular 调用时,Windows 身份验证不适用于 WebAPI

必需属性不适用于Angular Js中的文件输入