Angular FormArray 未更新其有效性且控制无效

问题描述 投票:0回答:1

我正在研究具有以下形状的动态形式:

FormArray
  |->FormGroup
      |->FormControl

当我想在客户端验证我的表单时,我运行以下函数来更新所有元素的有效性。

function updateValueAndValidityForAllChildren(abstractControl: AbstractControl, emitEvent = true) {
  if (abstractControl instanceof UntypedFormArray) {
    const formArray = <UntypedFormArray>abstractControl;
    _forEach(formArray.controls, (control) => {
      updateValueAndValidityForAllChildren(control, emitEvent);
    });
    abstractControl.updateValueAndValidity({ onlySelf: true, emitEvent });
  } else if (abstractControl instanceof UntypedFormGroup) {
    const formGroup = <UntypedFormGroup>abstractControl;
    _forEach(formGroup.controls, (control) => {
      updateValueAndValidityForAllChildren(control, emitEvent);
    });
    abstractControl.updateValueAndValidity({ onlySelf: true, emitEvent });
  } else if (abstractControl instanceof UntypedFormControl) {
    abstractControl.updateValueAndValidity({ onlySelf: true, emitEvent });
  }
}```

This worked perfectly in Angular 16 but since we upgraded to 18 we have an odd bug that makes the FormArray to be valid when the FormGroup is invalid. In turn the form is valid when it should be invalid.

We have looked into the validators to make sure the values were correctly set and it looks OK.

Is this something that has been encountered before ? How to fix this ?
angular typescript formarray formgroups
1个回答
0
投票

我认为您遇到的 FormArray 显示为有效而 FormGroup 无效的问题与 Angular 处理控件更新和验证器的新方式有关。这不是一个错误,但最近对 Angular 反应形式的一些更改可能会影响行为,尤其是 updateValueAndValidity。

你可以尝试:

  1. 确保您的“FormGroup”和“FormArray”包含正确的验证器,并且在更改时一致地重新评估它们。验证器可能需要根据状态或数据模型动态重新连接。

  2. 更新顺序问题:可能存在竞争条件或不正确的更新顺序,尤其是对于嵌套结构。我建议从 updateValueAndValidityForAllChildren() 开始,然后仅在根级别更新完成后调用它。这可能会避免中间不一致的状态。

    函数 updateAllControls(abstractControl: AbstractControl) { if (untypedFormGroup 的抽象控制实例 || UntypedFormArray 的抽象控制实例) { AbstractControl.controls.forEach(control => updateAllControls(control)); } AbstractControl.updateValueAndValidity({ onlySelf: false }); }

  3. Angular 18 迁移注意事项:仔细检查您的验证器是否有状态或包含可能已更改 Angular 18 中的行为的异步逻辑。Angular 的较新版本强调表单中的不变性,因此动态更新验证器可能需要使用

     正确重新实例化它们setValidators()
    随后是
    updateValueAndValidity()

  4. 避免不必要的排放:尝试在递归更新期间将

    emitEvent
    设置为
    false
    ,以防止子控件的多次排放可能干扰验证逻辑。

© www.soinside.com 2019 - 2024. All rights reserved.