首页 > 解决方案 > 等待 asyncValidator 完成的反应式 Angular 表单

问题描述

我正在构建一个反应式表单,当我提交表单时,我检查表单是否有效,有时我会得到表单无效,但那个时候控制台打印表单是有效的并且表单状态也是有效的。如果我删除AsyncValidator我不会遇到任何问题..

这是我的代码片段:AsyncDirective:

import { Directive, Input } from '@angular/core';
import { AbstractControl, AsyncValidator, NG_ASYNC_VALIDATORS, ValidationErrors } from '@angular/forms';
import { Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged, first } from 'rxjs/operators';
import { SupportersService } from 'src/app/pages/settings/view-supporters/supporters.service';
import { validateEmail } from '../functions/validator';

@Directive({
  selector: '[emailExistCheck]',
  providers: [{
    provide: NG_ASYNC_VALIDATORS, useExisting: EmailExistCheckDirective, multi:
      true
  }]
})
export class EmailExistCheckDirective implements AsyncValidator {
  @Input() emailExistCheck: { player_id: AbstractControl };

  constructor(private supporterService: SupportersService) { }

  validate(c: AbstractControl): Observable<ValidationErrors | null> {
    return this.checkEmailExist(c.value)
      .pipe(
        debounceTime(500),
        distinctUntilChanged(),
        first()
      )
  }

  checkEmailExist(email: string) {
    let player_id = this.emailExistCheck.player_id ? this.emailExistCheck.player_id : 'new_player';
    let isValid = validateEmail(email);
   
    return new Observable(observer => {
      
      if (isValid) {
          this.supporterService.checkExistEmail(email, player_id)
            .subscribe((result: any) => {
             
              if (result && result.is_exist) {
                observer.next({ invalid: true, message: 'Email already exist' });
              } else {
                observer.next(null)
              }
            })
      } else {
        observer.next(null)
      }

    })
  }
}

提交表格:

console.log(this.playerAddForm.valid) // when it show true but it goto else block
if(this.playerAddForm.valid){

}else{
//my code go here, but no invalid control I found here
     const controls = this.playerAddForm.controls;
      for (const name in controls) {
        if (controls[name].invalid) {
          invalid_control_name += ', ' + name;
        }
      }
}

标签: angular

解决方案


推荐阅读