有条件地实施 Angular 电子邮件验证程序不同步

Conditionally implemented Angular Email Validator fires out-of-sync

我只想在提供电子邮件地址时验证电子邮件地址。根据我的理解,您可以通过订阅 valueChanges 函数并根据提供的逻辑附加验证器来执行此操作。但是,当我这样做时,验证器不会在正确的时间触发。空字符串将被设置为无效,但单个字符将被标记为有效。

我的示例代码,来自模板:

<form [formGroup]="formGroup">
  Email: <input formControlName="email" type="text">
</form>

并且来自组件:

public ngOnInit(): void {
  this.formGroup = this._formBuilder.group({
    email: new FormControl()
  });

  this.formGroup.get('email').valueChanges.subscribe(value => {
    if (value.length > 0) {
      this.formGroup.get('email').setValidators(Validators.email);
    } else {
      this.formGroup.get('email').clearValidators();
    }
    this.formGroup.updateValueAndValidity();
  });
}

您可以在此处查看实际效果:https://plnkr.co/edit/5RiNDFKrTJ5iHJfVtmU5

在文档中 AbstractControl.updateValueAndValidity 说它将更新其祖先的有效性。在这种情况下,在父 FormGroup 上调用它似乎不会更新子电子邮件控件。

解决方案应该是在电子邮件控件本身上调用 updateValueAndValidity,但是当发生这种情况时,它会导致 valueChanges 接收一个新值,这将导致无限循环。通过传递选项 {emitEvent: false} 它应该绕过 valueChanges 并按预期运行。

this.formGroup.get('email').valueChanges.subscribe(value => {
  if (!this.formGroup.get('email').value) {
    this.formGroup.get('email').clearValidators();
  } else {
    this.formGroup.get('email').setValidators(Validators.email);
  }
  this.formGroup.get('email').updateValueAndValidity({emitEvent: false});
});