Angular FormControl XNOR 验证器,用于基于具有值或为空的两个字段



我在 4 个表单组上有两个字段。 其中 2 个是纯必需的,所以这很简单。另外两个必须要么都是空的,要么都有一个值 - 基本上是一个 XNOR 状态。

s1_male     s1_female      s1_male_valid     s1_female_valid
empty       empty          true              true
value       empty          false             false
empty       value          false             false
value       value          true              true

下面的代码有效,但它没有正确更新 UI。例如,如果我在s1_male中输入一个值,那么它会标记为无效,但s1_female不会。如果我随后在s1_female中输入一个值,该值仍然有效s1_male但仍被标记为无效。然后,我必须返回到s1_male并删除并重新输入值,或者更改它,然后将其更改回我想要的值。

在下面的函数中,我尝试在两个字段上调用updateValueAndValidity(),但这只会导致 Chrome 最终杀死的无限循环。

formGroup.addControl('rx_male', new FormControl('', Validators.required));
formGroup.addControl('rx_female', new FormControl('', Validators.required));
formGroup.addControl('s1_male', new FormControl('', this.scaleOptionValidator(formGroup)));
formGroup.addControl('s1_female', new FormControl('', this.scaleOptionValidator(formGroup)));
// these line cause endless loop
formGroup.controls.s1_male.valueChanges.subscribe(value => {
formGroup.controls.s1_female.updateValueAndValidity();
});
formGroup.controls.s1_female.valueChanges.subscribe(value => {
formGroup.controls.s1_male.updateValueAndValidity();
});
...
private scaleOptionValidator(formGroup: FormGroup): ValidatorFn {
return (control: AbstractControl): { [key: string]: boolean } | null => {
let isValid = false;
const female = formGroup.controls.s1_female;
const male = formGroup.controls.s1_male;
if (male && female) {
if ((male.value && female.value) || (!male.value && !female.value)) {
isValid = true;
}
return isValid ? null : { scalseNotValid: true };
}
return null;
};
}

建议会很棒

更新: 所以看起来表单组方法正在工作,但是我在这里使用 Ionic 并且令人沮丧,即使应用 ng 无效类,离子有效类也会覆盖 UI 样式,直到选择然后取消选择输入字段。

当我需要验证注册表单中的 2 个密码字段时,这就是我所做的。

shouldMatch(group: FormGroup): ValidationErrors | null {
const password = group.get("password")
const retypedPassword = group.get("retypedPassword")
if (password !== null && retypedPassword !== null) {
return password.value === retypedPassword.value ? null : { mismatch: true }
} else {
throw new Error("The form group is invalid. The group does not have a 'password' and/or a 'retypedPassword' control.")
}
}

您可以使用类似的方法。在我的注册FormGroup中,我为密码添加了内部FormGroup。然后我向该组添加了一个验证器。我使用内部组的有效性状态来显示错误消息。


您可以添加 getter 以减少在模板中编写的代码量。

get passwords(): FormGroup {
return this.signupForm.get("passwords") as FormGroup
}

最新更新