在我的Angular 4应用程序中,我有一个包含多个控件的表单。
在某些方面,我需要强制更新其有效性,所以我正在做:
this.form.get('control1').updateValueAndValidity();
this.form.get('control2').updateValueAndValidity();
this.form.get('control3').updateValueAndValidity();
// and so on....
然后:
this.form.updateValueAndValidity();
这很好。
但是我想知道是否有更好的方法来完成相同的事情,只需在父窗体上调用一个方法。
根据其documentation,updateValueAndValidity()
方法:
默认情况下,它还会更新祖先的值和有效性。
但在我的情况下,我需要更新其后代的价值和有效性。所以我可以摆脱许多代码。
答案 0 :(得分:14)
我在相同的情况下需要在嵌套级别的控件上更新FormGroup | FormArray
。
检查一下(为我工作):
/**
* Re-calculates the value and validation status of the entire controls tree.
*/
function updateTreeValidity(group: FormGroup | FormArray): void {
Object.keys(group.controls).forEach((key: string) => {
const abstractControl = group.controls[key];
if (abstractControl instanceof FormGroup || abstractControl instanceof FormArray) {
updateTreeValidity(abstractControl);
} else {
abstractControl.updateValueAndValidity();
}
});
}
答案 1 :(得分:7)
目前无法使用AbstractControl本身更新AbstractControl(FormGroup,...)的后代。也许在将来的版本中它是可能的。
https://github.com/angular/angular/issues/6170
https://github.com/angular/angular/issues/22166
更新:拉取请求已经打开 https://github.com/angular/angular/pull/19829
答案 2 :(得分:1)
我遇到了同样的问题,其中一个问题是,听valueChanges
可观察并触发updateValueAndValidity
来运行我的验证程序会导致无休止的循环,因此可以解决(有点怪异吗?)我创建了组件变量validityCycleFired
并将其初始化为false,进行了切换并防止了失控循环:
const fireValidityCheck = () => {
if (this.validityCycleFired) return;
this.validityCycleFired = true;
this.passwordForm.get('old_password').updateValueAndValidity();
this.passwordForm.get('new_password').updateValueAndValidity();
this.passwordForm.get('confirm_new_password').updateValueAndValidity();
setTimeout(() => this.validityCycleFired = false, 15);
return;
};
this.passwordForm.valueChanges.subscribe(fireValidityCheck);
答案 3 :(得分:0)
我通过递归控件并手动触发更新来解决了与您类似的问题。 可能这不是最佳解决方案:
private triggerValidation(control: AbstractControl) {
if (control instanceof FormGroup) {
const group = (control as FormGroup);
for (const field in group.controls) {
const c = group.controls[field];
this.triggerValidation(c);
}
}
else if (control instanceof FormArray) {
const group = (control as FormArray);
for (const field in group.controls) {
const c = group.controls[field];
this.triggerValidation(c);
}
}
control.updateValueAndValidity({ onlySelf: false });
}
答案 4 :(得分:0)
validateFormFields(fields) {
try {
Object.entries(fields.controls).forEach((control: any) => {
if (typeof control[0] == 'Array'
) {
this.validateFormFields(control[1]);
} else {
if (control[1].controls) {
Object.entries(control[1].controls).forEach((c: any) => {
c[1].touched = true;
});
} else {
control[1].touched = true;
}
}
});
} catch (e) {
console.log(e);
}
}