问题描述
我正在尝试找出在 Angular 中实现跨领域验证的最佳方法.
I am trying to figure out the best way to implement cross field validation in Angular.
例如,我有一个选择字段,它使另一个字段成为必填字段.
For example, I have a select field that makes another field mandatory.
我希望能够:
- 如果字段无效,请更改字段的边框颜色
- 当字段变为必填项时,在字段前显示 *
- 显示一条特定的错误消息,说明违反了哪些验证规则.
到目前为止,我想出了三个解决方案,但它们对我来说并不那么令人信服.
So far, I came up with three solutions but they don't feel so convincing to me.
- 聆听选择字段的更改并更新第二个字段的验证器.
- 监听两个字段的变化并手动执行 setErrors
- 将验证提升到 formGroup(这可能会让人感觉非常麻烦,因为验证状态现在存储在 formGroup 中,而不是直接在 formControl 中可用).
这是一个 Stackblitz 实现,用于演示我的调查.
Here is a Stackblitz implementation that demos my investigations.
推荐答案
更新 - 更好的方法
在表单上创建 customValidator
并使用验证器将 setError
用于所需的控件.使用 setError
,让 Angular 为我们添加 ng-invalid
,广告我们不需要订阅值更改.见:
Create the customValidator
over the form and use the validator to use setError
to the control required. Using setError
, make that Angular adds ng-invalid
for us, ad we needn't subscribe to value change. See:
form: FormGroup = new FormGroup(
{
input1: new FormControl('optional'),
input2: new FormControl(null),
},
{ validators: this.customValidatorForm() },
);
customValidatorForm() {
return (form: FormGroup) => {
const error =
form.get('input1').value != 'optional' && !form.get('input2').value
? { required: true }
: null;
form.get('input2').setErrors(error); //<--see the setErrors
return error;
};
}
参见 stackblitz
旧答案
只需使用 customValidator
像:
form: FormGroup = new FormGroup({
input1: new FormControl('optional'),
input2: new FormControl(null, this.customValidator()),
});
customValidator() {
return (control: any) => {
if (!control.parent) return null;
let mandatory = control.parent.get('input1').value;
return mandatory != 'optional' && !control.value ? { required: true } : null;
};
}
不要求 control.parent
的另一个选项是使用 .bind(this)
.这允许我们在验证器内部访问我们组件的所有变量,当然还可以访问 this.form
:
Another option for not ask for control.parent
it's use .bind(this)
. This allow us have inside the validator to all the variables of our component, and of course access to this.form
:
form: FormGroup = new FormGroup({
input1: new FormControl('optional'),
input2: new FormControl(null, this.customValidator().bind(this)), //<--bind(this)
});
customValidatorBind() {
return (control: any) => {
if (!this.form) return null;
let mandatory = this.form.get('input1').value;
return mandatory != 'optional' && !control.value ? { required: true } : null;
};
}
好吧,因为我们希望当更改 input1
input2
被选中时,您需要使用,在创建表单后订阅 valueChanges
:
Well, as we want that when change input1
input2
was checked, you need use, after create the form subscribe to valueChanges
:
this.form.get('input1').valueChanges.subscribe(() => {
this.form.get('input2').updateValueAndValidity();
});
这篇关于实现 Angular 跨域验证的最佳方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!