这是我使用StackOverflow多年后的第一个问题,我会尽力做到最好。
我必须开发具有动态验证的动态表格,例如在法国(我工作的地方),我们有不同的地址样式:具有道路类型/道路名称和替代格式的标准方式。
this.adress = this.fb.group({
roadType: ['', Validators.required],
roadName: ['', [ Validators.required,
Validators.minLength(5),
Validators.maxLength(20)] ],
altRoad: ['', [ Validators.required,
Validators.maxLength(20)] ]
});
如您所见,在初始化时,需要3个输入。 我必须执行的规则是至少输入1个地址,因此我在valueChanges上放置了一些观察者,当我们输入一个Input时,其他地址格式的输入必须失去其“必需”的验证。
this.altRoadSubscription = this.adress.get('altRoad').valueChanges.subscribe(val => {
if (val && val !== ''){
this.form.controls['roadType'].clearValidators();
this.form.controls['roadType'].updateValueAndValidity();
this.form.controls['roadName'].clearValidators();
this.form.controls['roadName'].updateValueAndValidity();
} else {
this.form.controls['roadType'].setValidators(Validators.required);
this.form.controls['roadName'].setValidators(Validators.required);
}
}
});
this.roadTypeSubscription = this.adress.get('roadType').valueChanges.subscribe(val => {
const roadName = this.adress.controls['roadName'].value;
if ((!val || val === '') && (!roadName || roadName === '')){
this.adress.controls['altRoad'].setValidators(Validators.required);
} else {
this.adress.controls['altRoad'].clearValidators();
this.adress.controls['altRoad'].updateValueAndValidity();
}
});
this.roadNameSubscription = this.form.get('nomVoie').valueChanges.subscribe(val => {
if ((!val || val === '') && (!roadType || roadType === '')){
this.form.controls['altRoad'].setValidators(Validators.required);
} else {
this.form.controls['altRoad'].clearValidators();
this.form.controls['altRoad'].updateValueAndValidity();
}
})
其他需要验证的人才是真正重要的事情! 当我在一个地址和另一个地址之间切换时,我不想丢失我的 minLength 和 maxLength 验证,而不必构建通用/标准方法,以免将验证器存储在formControl。 (一切都将通过父级组件进行管理)
如何使用简单的setValidators()方法将单个验证器删除/添加到验证器列表,而不刷新其他所有验证器?
与/或
是否有黑客可以获取当前的验证者列表? (将它们临时存储并仅将setValidators()
与我们要保留的验证器一起使用)
我看到this question带出一个答案,但是由于“控件”的类型用作字符串,而不是AbstractControl.validator()
原型期望{ {1}})
答案 0 :(得分:0)
代替动态设置验证器,您可以保留它们并更新错误。
这只是意味着,如果某个字段的值是真实的,则其他字段不会出现required
错误。
类似于 this stackblitz 。
this.a1.valueChanges.subscribe(value => {
if(value) { this.a2.setErrors(this.updateRequiredError(this.a2.errors)); }
});
updateRequiredError(currentErrors: Object) {
let ret = {... currentErrors};
if (ret['required']) { delete ret['required']; }
if (!Object.keys(ret).length) ret = null;
return ret;
}