Angular 角度形式更新所有子控件的值和有效性
在我的Angular 4应用程序中,我有一个带有多个控件的窗体 在某些情况下,我需要强制更新其有效性,因此我正在做:Angular 角度形式更新所有子控件的值和有效性,angular,typescript,angular-reactive-forms,angular-forms,angular-validation,Angular,Typescript,Angular Reactive Forms,Angular Forms,Angular Validation,在我的Angular 4应用程序中,我有一个带有多个控件的窗体 在某些情况下,我需要强制更新其有效性,因此我正在做: this.form.get('control1').updateValueAndValidity(); this.form.get('control2').updateValueAndValidity(); this.form.get('control3').updateValueAndValidity(); // and so on.... 然后: this.form.upd
this.form.get('control1').updateValueAndValidity();
this.form.get('control2').updateValueAndValidity();
this.form.get('control3').updateValueAndValidity();
// and so on....
然后:
this.form.updateValueAndValidity();
这个很好用
然而,我想知道是否有更好的方法来完成同样的事情,只需在父窗体上调用一个方法
根据its,updateValueAndValidity()
方法:
默认情况下,它还将更新其祖先的值和有效性
但在我的例子中,我需要更新其子代的值和有效性。因此,我可以去掉许多行代码。目前不可能用AbstractControl本身更新AbstractControl(FormGroup,…)的后代。也许在未来的版本中,这是可能的 更新:拉取请求已打开
通过递归控件并手动触发更新,我解决了与您类似的问题。 这可能不是最佳解决方案:
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 });
}
我在嵌套级别控件上更新
FormGroup | FormArray
时遇到了同样的情况
看看这个(为我工作):
/**
*重新计算整个控件树的值和验证状态。
*/
函数updateTreeValidity(组:FormGroup | FormArray):void{
Object.key(group.controls).forEach((key:string)=>{
const abstractControl=group.controls[key];
if(FormGroup的abstractControl实例| | FormArray的abstractControl实例){
updateTreeValidity(abstractControl);
}否则{
abstractControl.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);
您是否尝试了一些东西来查看它是否更新了其子体?类似于?。。。不先直接调用子体的方法?我原以为
updateValue和validity
也适用于子表单。是的,当然,这个问题并不有趣。我认为它不是现成的,在这种情况下,markAsDirty
也存在同样的问题:我认为您需要做一些变通,迭代父控件中的对象属性,并在每个控件上使用updateValue和validity
。嗯。这将是方便的,因为它将是可用的,只要调用它的家长。标记为触摸的控制是什么遗漏了在其他答案!
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);