有条件实施的Angular Email Validator会触发不同步

时间:2018-03-01 23:45:40

标签: angular angular-forms angular2-formbuilder

我只想在提供地址时验证电子邮件地址。根据我的理解,您可以通过订阅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

1 个答案:

答案 0 :(得分:1)

在文档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});
});