条件验证器可能被问了很多次。但我永远找不到这个验证器何时被调用。
假设我有一个只有两个字段的表单
this.form = formBuilder.group({
emailRequired: [false],
emailRecipients: ['']
});
我现在希望仅当
emailRecipients
字段设置为 emailRequired
时,字段 true
才有必需的验证器。我想出了这个
const emailRecipientsControl = fb.control('', {
validators: [
(x) =>
{
// When emailRequired is set to true, the email control is required.
if (x.parent?.get('emailRequired').value)
{
return { required: true }
};
return null;
}
]
});
this.form = this.fb.group({
emailRequired: [false],
emailRecipients: emailRecipientsControl
});
这实际上有点工作,但问题是我的自定义验证器仅在
emailRecipients
值更改时才被调用,而我需要在 emailRecipients
或 emailRequired
都更改时调用它。
总结一下:如何定义何时调用(自定义)控件验证?
注意:我的真实表单比这个示例大得多,我不想订阅整个表单。
您需要订阅 valuechanges 并添加/删除验证器。
this.form = formBuilder.group({
emailRequired: [false],
emailRecipients: ['']
});
this.form.controls.emailRequired.valueChanges.pipe(
/*unsubscription*/,
).subscribe(isRequired => {
if (isRequired) {
this.form.controls.emailRecipients.addValidators(Validators.required);
} else {
this.form.controls.emailRecipients.removeValidators(Validators.required);
}
this.form.controls.emailRecipients.updateValueAndValidity();
});
正如你所说,如果你不使用 setValue 或更改输入,Angular 不会“自动验证”输入。因此,更简单的解决方案是在更改复选框时强制进行此验证
<input type="check" formControlName="emailRequired"
(input)="form.controls.emailRecipients.updateValueAndValidity()">
更新 基于@MoxxiManagam 的推荐。如果我们可以定义我们的 formGroup 并且当我们需要订阅 valueChanges 或使用(输入)时不需要考虑会更好。
我们可以定义一个“valitador”,比如
export function checkControl(controlName:string)
{
return (x:AbstractControl) =>
{
const control=x?.parent?.get(controlName);
if (control)
control.updateValueAndValidity()
return null;
}
}
这让我们可以写
form = new FormGroup({
emailRequired: new FormControl(false,checkControl('emailRecipients')),
emailRecipients: new FormControl('',requireIf('emailRequired'))
});
那么我们就简单了
<form [formGroup]="form">
<input type="checkbox" formControlName="emailRequired">
<input formControlName="emailRecipients">
{{form.get('emailRecipients')?.errors|json}}
</form>
注意:验证器“requiredIf”就像
export function requireIf(controlName:string)
{
return (x:AbstractControl) =>
{
if (x?.parent?.get(controlName)?.value && !x.value)
{
return { required: true }
};
return null;
}
}
看到,当我们更改“复选框”时,formControl
form.controls.emailRecipiens
是updateAndValidity。
嗯,这个“验证器”使典型的重复密码验证器问题变得更加“稳健”。
export function equalsTo(controlName:string)
{
return (x:AbstractControl) =>
{
const control=x?.parent?.get(controlName);
if (control && control.value && control.value!=x.value)
{
return { notMatch: true }
};
return null;
}
}
表格
form2=new FormGroup({
password:new FormControl('',checkControl('repeatPassword')),
repeatPassword:new FormControl('',equalsTo('password'))
})