Angular表单自定义验证器null返回不从表单中删除错误

时间:2018-02-20 23:20:14

标签: javascript angular typescript angular-reactive-forms custom-validators

所以我创建了一个自定义验证器来验证确认密码输入是否与原始条目匹配。工作良好。但是,我允许这两个字段都是空白的,因为这是在某人可以在他们的设置中更改密码的页面上,当然他们可能不想这样做。如果两个表格都是空白的,那么该表格应该有效,以便可以提交该表格,并且可以更新其他设置以查找其个人资料,但是发生了一些奇怪的事情。

表格道具:

passControl = new FormControl('', [
  FormValidation.checkPasswordStrength()
]);

passConfirmControl = new FormControl('', [
]);

profileForm = new FormGroup(
  {
    password: this.passControl,
    passwordConfirm: this.passConfirmControl
  },
  {
    validators: FormValidation.checkPasswordsMatch()
  }
);

这是我的验证功能:

static checkPasswordsMatch(): ValidatorFn {
  return (control: AbstractControl): {[key: string]: any} => {
    let passwordCtrl = control.get('password');
    let passwordConfirmCtrl = control.get('passwordConfirm');

    // allow blank for when they don't want to change password
    if (passwordCtrl.value === '' && passwordConfirmCtrl.value === '') {
      console.log('both are blank');
      return null;
    }

    if (passwordCtrl.value !== passwordConfirmCtrl.value) {
      console.log('hit mismatch passwords');
      control.get('passwordConfirm').setErrors( { passwordMatch: true } );
    }

    return null;
  };
}

因此,当表单加载时,它实际上有效,我看到both are blank。但是,如果你触摸密码字段并输入一些东西,当然它显示现在它们不匹配,但当你删除你在那里输入的内容时,那么该函数显示它们都是空的,但错误仍然存​​在,表单保持无效,除非您还触摸passwordConfirm字段,也键入内容并将其删除。我错过了什么?

1 个答案:

答案 0 :(得分:1)

您正在passwordConfirm FormControl上设置错误,验证程序在运行时不会生效。如果您希望错误消失,您需要将验证器应用于特定的FormControl,或者您需要确保在先前的测试成功时从控件中删除错误。

通常,您将在验证程序中返回错误,而不是在特定的FormControl上设置它。正如您所知,除非您手动从FormControl中删除错误,否则它会一直存在。验证器只会更改它们绑定的控件的错误对象。

通常,只要发生错误就会返回错误。

return { passwordMatch: true };

或者如果您想同时执行这两项操作并手动设置FormControl错误。

// allow blank for when they don't want to change password
if (passwordCtrl.value === '' && passwordConfirmCtrl.value === '') {
  console.log('both are blank');
  control.get('passwordConfirm').setErrors(null);
  return null;
}

if (passwordCtrl.value !== passwordConfirmCtrl.value) {
  console.log('hit mismatch passwords');
  control.get('passwordConfirm').setErrors( { passwordMatch: true } );
  return { passwordMatch: true }
}

同样只是一个挑剔的迂腐的事情,你应该尝试使你的错误在逻辑上可读。因此,当您测试密码是否匹配时,请passwordMatch: true表示密码匹配。在错误而不是测试之后命名错误可能会更好,例如: passwordsDoNotMatch: true。这说明密码不匹配,这是对通过表单呈现的问题的更准确描述。