【问题标题】:Add async validator to FormControl dynamically将异步验证器动态添加到 FormControl
【发布时间】:2020-01-14 22:57:40
【问题描述】:

我在 Angular 8 中做一个 Web 应用程序。我有一个只有 1 个输入的表单来输入一个 5 位数字(作为字符串)。我想验证这个数字在数据库中是唯一的。

我试图实现一个异步验证器。我需要将一些变量传递给它,所以我稍后会动态添加验证器。

brand: Brand;
raffle: Raffle;

constructor(
    private brandService: BrandService,
    private fb: FormBuilder,
  ) {
    this.gambleForm = fb.group({
      number: ['', [ // Default validators
        Validators.required,
        Validators.minLength(5),
        Validators.maxLength(5),
      ]]
    });
  }

ngOnInit() {
    const id = this.route.snapshot.paramMap.get('id');
    this.getBrandData(id);
  }

getBrandData(id: string) {
    this.brandService.getBrandById(id).subscribe(res => {
      this.brand = res;
      this.getRaffleData();
    });
  }

getRaffleData() {
    this.brandService.getLastRaffleOpen(this.brand.id)
      .subscribe(res => {
        this.raffle = res;
        // Adding validators dynamically
        this.gambleForm.get('number').setValidators([
          // Returns a compose validator containing all previously defined validators.
          this.gambleForm.get('number').validator,
          // Async validator
          CustomValidator.numberCanBePlayed(
            this.brandService.getFirestore(),
            this.brand.id,
            this.raffle.id
          )
        ]);
      });
  }

现在,我的异步验证器无法正常工作,因为根据我所阅读的内容,我将其指定为同步验证器,而不是异步。如何正确分配异步验证器?我稍后会分配它,因为我需要将一些变量传递给异步验证器,这些变量在表单的构造中不可用。

我的目标是动态分配我的异步验证器。

【问题讨论】:

    标签: angular angular-reactive-forms


    【解决方案1】:

    FormControl 有一个特殊的方法:setAsyncValidators: https://angular.io/api/forms/AbstractControl#setAsyncValidators

    【讨论】:

      【解决方案2】:

      您可以在后端出现错误时尝试此操作,并在对应的 formControl 上使用 setErrors ,这是一个检查电子邮件是否被接收的示例

      subscribe((data) => {// do control here},
         error => { 
          if(error.status === 400 && error.error.errors.email) {
            const emailFormControl = this.accountForm.get('email');
            if (emailFormControl) {
            // activate the error message
            emailFormControl.setErrors({
              serverError: 'Email exist déjà!'
            });
           }
          }
      });
      

      你可以像这样在模板中显示错误

      <mat-error *ngIf="accountForm.get('email').errors?.serverError">
                    {{ accountForm.get('email').errors?.serverError }}
      </mat-error>
      

      【讨论】:

        猜你喜欢
        • 2017-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-26
        相关资源
        最近更新 更多