【问题标题】:Async custom validator not working and showing error message in Angular 8异步自定义验证器不起作用并在 Angular 8 中显示错误消息
【发布时间】:2020-03-19 04:36:05
【问题描述】:

我是 Angular 8 的新手,正在尝试创建自定义异步验证器。以下是我的代码:

在我的打字稿文件中,我正在创建如下所示的表单字段。我只使用异步验证器(没有同步验证器,因此将“null”作为第二个参数传递):

group.addControl(control.Name, this.fb.control('', null, this.phoneValidator));

下面是我的异步验证器代码:

phoneValidator(control: AbstractControl) {
    if(control.value == '' || control.value == undefined || control.value == null) {
      return null;
    }
    else {
      return this.phoneValidatorServiceCall(control.value)
        //.pipe(map((data: any) => {
        //  return (data.Response == "True" ? null : { phoneValidator: true });
        //}))
        .subscribe(data => {
            return (data.Response == "True" ? null : { phoneValidator: true });
        })
      }
   }

在上面的代码中,我尝试使用“管道”,但它不起作用,所以只使用了“订阅”,但即使这样也不起作用。下面是我的服务方式:

phoneValidatorServiceCall(input): Observable<any> {
   return this.http.post<any>('http://xxxxxxxx:xxxx/validate/phone', { 'Text': input });
}

为了在 html 中显示错误,我使用以下代码:

<mat-form-field class="example-full-width">
<input #dyInput [formControlName]="Phone" matInput [placeholder]="Phone" [required]="IsRequiredField">

<!-- For showing validation message(s) (Start) -->
<mat-error *ngFor="let v of Config.Validators">
  {{ f.controls['Phone'].invalid }} // comes true only on error
  {{ f.controls['Phone'].hasError("phoneValidator") }} // always coming false even for wrong input
  <strong *ngIf="f.controls['Phone'].invalid && f.controls['Phone'].hasError('phoneValidator')">
    {{ My Message Here }}
  </strong>
</mat-error>
<!-- For showing validation message(s) (End) -->

我面临两个问题:

  1. 它不等待服务的响应。不知何故,它总是从 phoneValidator(control: AbstractControl) 方法返回错误
  2. 错误消息未显示在屏幕上。 f.controls['Phone'].hasError("phoneValidator") 总是假的

【问题讨论】:

  • 对于你想要制作的一般任何东西aysnc await,你必须使用你的函数async validationFunction() { await this.data = this.serviceCall() }
  • 我认为您不应该订阅您的验证器。你应该只返回可观察的。像这样的东西:return this.phoneValidatorServiceCall(control.value).pipe(...)
  • 感谢@GaurangDhorda 的回复。你能举个例子吗?
  • 感谢@AndreiGătej 的回复。我只尝试了管道,但它不起作用。
  • stackblitz.com/edit/angular-5hwcff 这个 stackblitz 链接可以帮助你

标签: angular angular8 angular-observable


【解决方案1】:

有几个问题-

  1. phoneValidator 的返回类型应该是Promise&lt;ValidationErrors | null&gt; | Observable&lt;ValidationErrors | null&gt;
  2. 执行以下操作,以便返回一个 observable 并检查您的第二个问题是否得到解决 -

return observableOf({ phoneValidator: true });

  1. 使用管道并映射您的响应。

【讨论】:

    【解决方案2】:

    您已获得有关如何解决问题的好建议。那些聚集...所以你目前的问题是:

    添加验证器的返回类型:

    Observable<ValidationErrors | null>
    

    因为那是你要返回的东西。

    所以不要订阅验证器,而是返回 observable。此外,您需要在有效时 return of(null),因为再次......我们需要返回一个 observable。因此,将您的验证器修改为:

    import { of } from 'rxjs';
    
    //....
    
    phoneValidator(control: AbstractControl): Observable<ValidationErrors | null> {
      if (!control.value) {
        return of(null);
      } else {
        return this.phoneValidatorServiceCall(control.value)
          .pipe(map((data: any) => {
            return (data.Response == "True" ? null : { phoneValidator: true });
          }))
      }
    }
    

    【讨论】:

    • 感谢@AJT82,但每次它都返回错误。
    • data.Response == "True" 是真的吗?你检查过吗? console.log(data) 产生什么?如果你正在做[formControlName]="Phone"f.controls['Phone'].invalid 也可能是错误的。
    • data.Response 在电话号码验证时为“True”,否则返回“False”。响应是正确的,但 f.controls['Phone'].invalid 总是正确的。那是问题
    • f.controls['Phone'].invalid 实际上是一个表单控件,对吧?您的表单如下所示:this.f = this.fb.group({Phone: ''})?请提供minimal reproducible example,否则真的很难提供帮助,但我怀疑应该是f.controls[Phone].invalid
    • 这是一个工作示例,它总是返回错误:stackblitz.com/edit/angular-h9k5qp-pd7ju3?file=app/… Please fork the stackblitz 并在那里重现问题。
    猜你喜欢
    • 2021-02-02
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    • 2018-08-09
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多