使用 FormArray 重置表单时删除字段错误

Remove field errors when resetting a form with a FormArray

在我的 Angualar 应用程序中,我有一个表单,其中包含多个文本字段,例如订单 ID 和订单日期。我的表单还有一个 FormArray,其中每个元素都是一个表示一行字段的 FormGroup。此表单数组在启动时有 1 个 FormGroup,可以通过单击按钮添加更多。提交表单后,我想在将数据发布到 REST 服务获得成功响应后重置表单。我的重置代码形式如下:

resetItems(): void {
  this.orderForm.reset();
  this.clearErrorsFromFormGroup(this.orderForm);
  let items = this.orderForm.get('items') as FormArray;
  items.controls = [];
  this.addItem();
  this.clearErrorsFromFormGroup(items.at(0) as FormGroup);


}

  private clearErrorsFromFormGroup(formGroup: FormGroup): void {
    Object.keys(formGroup.controls).forEach(key => {
      formGroup.controls[key].setErrors(null);
    });
  }


执行上述操作时,订单 ID 和订单日期等顶级字段会被重置,并且不会以红色突出显示,因为我已删除错误。我想将我的表单数组设置为与启动 1 个元素时相同的方式。我的代码清除了表单数组并添加了一个 rowData 元素。然后我清除了 rowData FormGroup 的错误。在 UI 上,此 rowData 的字段已全部清除,但即使我已清除错误,它们也会突出显示为红色。有人可以帮忙吗?

我在 https://stackblitz.com/edit/angular-8qjphu

中包含了一个 StackBlitz link 来演示这一点

重置后尝试使用formGroup.updateValueAndValidity()方法

itemsFormArray,您清除控件的方式将不起作用。

检查此代码

 Object.keys(formGroup.controls).forEach(key => {
      formGroup.controls[key].setErrors(null);
    });

假设您在此处按下 items

formGroup.controls['item'] // this is a FormArray and 
// not FormControl so setErrors(null) won't work here

解决此问题的一种方法是检查 FormArray 的实例,然后在控件字段上迭代,您可以使用 clearValidatorsupdateValueAndValidty 函数。

   if (formGroup.controls[key] instanceof FormArray) {
         const control = formGroup.get(key) as FormArray;
        for (let i = 0; i < control.controls.length; i++) {
          const formGroup = control.controls[i] as FormGroup;
          Object.keys(formGroup.controls).forEach(field => {
            const control = formGroup.get(field);
            control.clearValidators();
            control.updateValueAndValidity();
          });
        }
      }

这是一个 stackblitz 演示: https://stackblitz.com/edit/angular-f7pflm?file=src%2Fapp%2Fapp.component.ts

这是您的 clearErrorsFromFormGroup 现在的样子

private clearErrorsFromFormGroup(formGroup: FormGroup): void {
    Object.keys(formGroup.controls).forEach(key => {
      formGroup.controls[key].setErrors(null);
       if (formGroup.controls[key] instanceof FormArray) {
         const control = formGroup.get(key) as FormArray;
        for (let i = 0; i < control.controls.length; i++) {
          const formGroup = control.controls[i] as FormGroup;
          console.log('control', control);
          Object.keys(formGroup.controls).forEach(field => {
            const control = formGroup.get(field);
            control.clearValidators();
            control.updateValueAndValidity();
          });
        }
      }

    });
  }