Angular 角度-动态添加/删除验证程序
我有一个Angular 角度-动态添加/删除验证程序,angular,angular-forms,angular-validation,Angular,Angular Forms,Angular Validation,我有一个FormGroup定义如下: this.businessFormGroup: this.fb.group({ 'businessType': ['', Validators.required], 'description': ['', Validators.compose([Validators.required, Validators.maxLength(200)])], 'income': [''] }) 现在,当businessType为Other时,
FormGroup
定义如下:
this.businessFormGroup: this.fb.group({
'businessType': ['', Validators.required],
'description': ['', Validators.compose([Validators.required, Validators.maxLength(200)])],
'income': ['']
})
现在,当businessType
为Other
时,我想从description
中删除验证器。必需的验证器。如果businessType
不是Other
,我想重新添加验证器
我正在使用下面的代码动态添加/删除验证器。必需
。但是,它会清除现有的验证器.maxLength
验证器
if(this.businessFormGroup.get('businessType').value !== 'Other'){
this.businessFormGroup.get('description').validator = <any>Validators.compose([Validators.required]);
} else {
this.businessFormGroup.get('description').clearValidators();
}
this.businessFormGroup.get('description').updateValueAndValidity();
if(this.businessFormGroup.get('businessType').value!=='Other'){
this.businessFormGroup.get('description').validator=Validators.compose([Validators.required]);
}否则{
this.businessFormGroup.get('description').clearValidators();
}
this.businessFormGroup.get('description').updateValueAndValidity();
我的问题是,在添加/删除required
验证器时,如何保留现有的验证器 Angular forms有一个内置函数,可以通过编程方式分配验证器
例如,您可以执行以下操作:
if(this.businessFormGroup.get('businessType').value !== 'Other'){
this.businessFormGroup.controls['description'].setValidators([Validators.required, Validators.maxLength(200)]);
} else {
this.businessFormGroup.controls['description'].setValidators([Validators.maxLength(200)]);
}
this.businessFormGroup.controls['description'].updateValueAndValidity();
重要的是要记住,通过使用此方法,您将覆盖现有的验证器,因此您需要为正在重置的控件包含您需要/想要的所有验证器。最简单的方法是在条件变量更改时设置控件的验证器。但是,通过使用一些间接+函数式编程,我们实际上可以做得更好
考虑存在一个描述所需的
getter,它充当boolan标志
想法:
- 创建一个自定义验证器函数,该函数将
descriptionIsRequired
作为参数,并根据它根据required+maxLength或maxLength验证控件
- 将自定义验证器绑定到描述控件,以便在评估控件的有效性时,应考虑所需的
descriptionIsRequired
的最新值
第一点很容易实现:
function descriptionValidator(required: boolean): ValidatorFn {
return (formControl: FormControl): ValidationErrors => {
if (required) {
return Validators.compose([Validators.required, Validators.maxLength(200)])(formControl);
} else {
return Validators.maxLength(200)(formControl);
}
}
}
请注意,这是一个自封装函数
第二点有点棘手,但最后看起来是这样的:
export class FooComponent {
constructor(){
this.form = fb.group({
description: ['initial name', this.validator()]
});
}
private get descriptionIsRequired(): boolean {
...
}
private validator(): ValidatorFn {
return (c: FormControl): ValidationErrors => descriptionValidator(this.descriptionIsRequired)(c);
}
}
对正在发生的事情的一个小解释:
validator
方法返回一个函数
validator
返回的函数可以看作是一个工厂方法:无论何时调用它,都会返回一个新函数,更具体地说,就是使用最新的descriptionsrequired
值返回我们的descriptionValidator
的一个新实例
下面的现场演示可能会有所帮助:
将Validators.required添加到现有抽象控件的validatorset
:
if (c.validator !== null) {
c.setValidators([c.validator, Validators.required])
} else {
c.setValidators([Validators.required])
}
这个对我有用
onAddValidationClick(){
this.formGroup.controls["firstName"].setValidators(Validators.required);
this.formGroup.controls["firstName"].updateValueAndValidity();
}
onRemoveValidationClick(){
this.formGroup.controls["firstName"].clearValidators();
this.formGroup.controls["firstName"].updateValueAndValidity();
}
任何仍在寻找答案的人,你可以这样做,在ngOnInit()或任何你喜欢的地方处理
const validators = formGroup.validator; /* or control.validator */
const newValidator = CustomValidator.checkUserNameValidity();
/* Add to existing validator */
if(validator) {
formGroup.setValidators([validators, newValidator])
} else {. /* if no validators added already */
formGroup.setValidators([newValidator]);
}
同样遵循asyncValidator的相同操作。如果您多次更改“需要验证程序”(例如,使用复选框),则应添加以下内容:
this.formGroup.controls["firstName"].setErrors(null);
因此:
如果您多次更改“需要验证程序”(例如,使用复选框),则应添加以下内容:
非常重要的领域!
this.formGroup.controls[“firstName”].setErrors(null) 验证器像一个数组一样存储,您需要处理自己应用的验证器列表。遗憾的是,这是不可能的,angular似乎会在内部合并应用的验证器,因此您只能调用clear
和set
functions@Ricardo那是错误的,验证器由一个函数组成,就是这样。在当前的API实现中,无法检查为控件设置了哪些验证器请注意,setValidators将覆盖以前设置的验证器,这意味着maxLength将被覆盖,并且不会使用此方法重新生成谢谢@Jota.Toledo。这是一个需要注意的重要行为。更新了答案以包含它。我认为使用考虑了业务类型和描述的customValidator是“更自然的”删除/添加的想法validators@Eliseo您是对的,拥有一个自定义验证器是更好的方法,但在我的例子中,我在json文件中定义了验证规则,我正在寻找一个更通用的实现,Narm提供的解决方案可能是最好的选择。对我来说,这只在之后调用updateValueAndValidity()后才起作用,正如链接文档(使用Angular version 8)+1中所建议的那样,这是一个有效的解决方案,但我正在寻找一个更通用的实现,因为我的验证规则是在json文件中定义的。我想知道在这种情况下,泛型是什么意思。我所看到的将其推广的唯一方法是,您有一组验证器V
,这些验证器必须在控件中始终处于活动状态。他们从哪里来无关紧要。然后您有另一个验证器集合Vop
,在本例中,该集合中仅包含必需项,根据布尔条件,该集合可以在控件中处于活动状态,也可以不处于活动状态。我说得对吗?如果没有,请进一步解释“更通用”实现的概念。干杯!这让我有了一个好主意,可以做一些我需要做的一般性工作,比如处理setErrors(null);。但是updateValueAndValidity({onlySelf:true});它不起作用。
onAddValidationClick(){
this.formGroup.controls["firstName"].setValidators(Validators.required);
this.formGroup.controls["firstName"].updateValueAndValidity();
}
onRemoveValidationClick(){
this.formGroup.controls["firstName"].setErrors(null);
this.formGroup.controls["firstName"].clearValidators();
this.formGroup.controls["firstName"].updateValueAndValidity();
}