Angular Custom Async Validator 保持挂起状态

Posted

技术标签:

【中文标题】Angular Custom Async Validator 保持挂起状态【英文标题】:Angular Custom Async Validator stays in pending state 【发布时间】:2018-03-29 12:41:22 【问题描述】:

我有一个自定义验证器,用于验证用户的电子邮件是否唯一。

我在 *** 和互联网上搜索过相关主题,但没有任何帮助

当我在表单中提供输入(发送请求)时,请求保持在挂起状态并且不会解析。

我已经在 postman 中测试了后端,它按预期工作,问题出在客户端或角度方面。

验证函数如下:

emailUniqueValidator (control: AbstractControl): Promise<[key: string]: any> | Observable<[key: string]: any> 
    return new Promise((resolve, reject) => 
      this.userService.checkEmailUnique(control.value).subscribe((response: Response) => 
        const body = response.json();
        if (body.found === false) 
          resolve(null); // email is unique
         else 
          reject(emailUniqueValidator: true); // email is not unique
        
      );
    );
  

当我更改表单控件的值时,挂起的类会出现,但它会永远存在而不是得到解决。

我的邮件表单控件如下:

'email': new FormControl('', [
        Validators.required,
        Validators.email
      ], this.emailUniqueValidator.bind(this)
),

我的用户服务如下:

checkEmailUnique (email: string): Observable<Response> 
    return this.http.post('http://localhost:3000/user/email', email,  withCredentials: true );
  

为什么验证者没有及时解决并永远处于等待状态?

编辑:

以下代码可以很好地从服务中获取价值,我已经通过将响应记录到控制台来检查它。

如果电子邮件不存在于数据库中,则解决得很好,但如果电子邮件已经存在,则会引发错误并且状态保持挂起。

return new Promise((resolve, reject) => 
      this.userService.checkEmailUnique(control.value).subscribe((response: Response) => 
        console.log(response);
        response.json().found ? reject(emailUniqueValidator: true) : resolve(null);
      , (error: any) => reject(emailUniqueValidator: true));
);

【问题讨论】:

见github.com/angular/angular/issues/13200 有你的组件 ChangeDetectionStrategy.OnPush 吗? emailUniqueValidator (control: AbstractControl): Promise&lt;[key: string]: any&gt; | Observable&lt;[key: string]: any&gt; return this.userService.checkEmailUnique(control.value).pipe( debounceTime(500), distinctUntilChanged(), map(value =&gt; value.body.found ? emailUniqueValidator: true : null) ); 这个代码对我来说很好用@Eldar 【参考方案1】:

你为什么要通过承诺来包裹可观察到的头痛?试试这样:

emailUniqueValidator (control: AbstractControl): Observable<[key: string]: any> 
    return this.userService.checkEmailUnique(control.value)
               .map(r => r.json())
               .map(r => (r.found) ? emailUniqueValidator: true : null);
 

【讨论】:

我试过你的代码,但是状态仍然是pending,你能告诉为什么会这样吗? 你应该使用 do() 操作符来调试,看看是否有任何东西可以通过,这应该可以工作,有些问题在其他地方。【参考方案2】:

observable 永远不会完成。

尝试在末尾添加.first()

emailUniqueValidator (control: AbstractControl): Observable<[key: string]: any> 
    return this.userService.checkEmailUnique(control.value)
               .map(r => r.json())
               .map(r => (r.found) ? emailUniqueValidator: true : null)
               .first();
 

【讨论】:

较新的 rxjs 版本如下所示:this.userService.checkEmailUnique(control.value).pipe(map(r =&gt; r.json()), take(1)) 省略了一些细节以保持可读性,因为代码格式化选项在 cmets 中显然是有限的。【参考方案3】:

我遇到了同样的问题。我删除了changeDetection: ChangeDetectionStrategy.OnPush,它起作用了。一个例子is here。

【讨论】:

【参考方案4】:

确保您的“状态代码来自”服务在任何情况下都是 200

var user = _appRepository.GetUserByUserName(username);
if (user != null)

    return Ok(user );

return Ok();

这是来自 asp.net 核心 api。当用户不可用时发送空Ok()。如果角度捕获 404 或 400,则始终显示待处理。

export function uniqueUsernameValidator(userService: UserService): AsyncValidatorFn 
  return (c: AbstractControl): Observable< [key: string]: any  | null> => 
    return userService.getUserByUsername(c.value).pipe(
      map(users => 
        console.log(users)
        if (users) 
          return  'unique': true;
        else 
          return null
        
      )
    )
  ;

【讨论】:

以上是关于Angular Custom Async Validator 保持挂起状态的主要内容,如果未能解决你的问题,请参考以下文章

测试 Angular 2 应用程序中的“CUSTOM_ELEMENTS_SCHEMA”错误

angular 2 custom sort pipe 请帮帮我

如何通过新的 @angular/cli v7 angular.json 或 custom-webpack.config.js 添加额外的 postcss 插件?

[Angular 2] Async Http

Angular Karma 使用 CUSTOM_ELEMENTS_SCHEMA 测试超时测试 AppComponent

[Angular Tutorial] 13 -REST and Custom Services