我想基于其他一些表单值对某些属性应用条件验证。我已经提到了一些答案Angular2: Conditional required validation,但是这些答案无法满足我的需求。因为我必须以大型企业应用程序的40多种形式(大约30个字段)实现条件验证。我不想在每个组件中编写相同的代码并更改FormControl名称。我不知道如何通过指令来实现。
如果年龄控制值v大于18,则必填字段为许可证号字段。
这是我的代码:
this.userCustomForm = this.angularFormBuilder.group({
age:['',Validators.required],
licenseNo:[''] // Here I want to apply conditional required validation.
});
在我的应用程序中,有些情况下我想基于嵌套的FormGroup或FormArray值设置条件验证。
请指导我,如何实现这一目标。
答案 0 :(得分:2)
我的建议是使用动态验证。
订阅userCustomForm的age字段中的更改,并在年龄达到需要验证许可证的条件时,使用setValidators()
动态添加validators.required,并随时使用clearValidators()
动态清除validators
this.userCustomForm.get('age').valueChanges.subscribe(val => {
if (condition) { // for setting validations
this.userCustomForm.get('licenseNo').setValidators(Validators.required);
}
if (condition) { // for clearing validations
this.userCustomForm.get('licenseNo').clearValidators();
}
});
答案 1 :(得分:1)
对我来说,它完美运行,就像这样:
this.userCustomForm.get('age').valueChanges.subscribe(val => {
if (condition) {
this.userCustomForm.controls['licenseNo'].setValidators([Validators.required]);
this.userCustomForm.controls['licenseNo'].updateValueAndValidity();
} else {
this.userCustomForm.controls['licenseNo'].clearValidators();
this.userCustomForm.controls['licenseNo'].updateValueAndValidity();
}
});
您必须更新表单的ValueValueValidity 才能使更改生效。
希望这会有所帮助!
答案 2 :(得分:1)
还有一种更通用的方法,可以用于多种用途,而不仅仅是这个用途。
每次要有条件地将 Validators.required 添加到控件中时,都可以使用此功能。
首先创建此函数(最好是在服务中使用,因为它是通用的,因此以后可以在不同组件中的不同条件下使用它,但例如,它在同一组件中)
import { FormGroup, Validators } from '@angular/forms';
conditionallyRequiredValidator(masterControlLabel: string, operator: string, conditionalValue: any, slaveControlLabel: string) {
return (group: FormGroup): {[key: string]: any} => {
const masterControl = group.controls[masterControlLabel];
const slaveControl = group.controls[slaveControlLabel];
if (eval(`'${masterControl.value}' ${operator} '${conditionalValue}'`)) {
return Validators.required(slaveControl)
}
slaveControl.setErrors(null);
return null;
}
}
masterControlLabel :该控件将有条件地将 Validators.required 添加到 slaveControl
operator :要用于将 masterControl 值与conditionalValue
进行比较的运算符conditionalValue :要使 masterControl 有条件地将验证器有条件地添加到 slaveControl
的任何值,slaveControlLabel :将接收(或不接收)条件 Validators.required
的控件第二,最后,像这样在您的formGroup中添加验证器参数(或验证器参数,如果需要进行多重验证):
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
constructor(
private angularFormBuilder: FormBuilder,
){ }
myFormGroup: FormGroup = this.angularFormBuilder.group({
age: ['', Validators.required],
licenceNo: [''],
}, {validator: conditionallyRequiredValidator('age', '>=', 18, 'licenceNo')});
在此示例中,如果年龄严格大于或等于18岁,则 licenseNo 控件将有条件地需要
答案 3 :(得分:1)
通过FormControl类的setValidators方法有条件地设置validator,即
this.userCustomForm = this.angularFormBuilder.group({
age:['', Validators.required],
licenseNo:['']
});
if (condition) {
this.userCustomForm.get('licenseNo').setValidators([
Validators.required
]);
}
答案 4 :(得分:0)
我通过这样做解决了这个问题:
this.userCustomForm = new FormGroup({
age: new FormControl('',Validators.required)
licenseNo: new FormControl('', condition ? Validators.required : [])
});
还有另一种方法可以使用 setValidators
和 clearValidators
方法执行此操作,请参见以下示例:
if(condition) {
this.userCustomForm.get('licenseNo').setValidators(Validators.required);
} else {
this.userCustomForm.get('licenseNo').clearValidators();
}