删除 *ngFor 中使用的 FormArray 项目会引发错误

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

在《学习 Angular 不废话》一书中,有一个我尝试改进的如何使用 FormArray 的示例。此示例使用基于包含产品的购物车的动态表单,我尝试添加删除购物车中的某些产品(通过使用 FormArray 集合中的 removeAt 方法)的可能性,但出现错误。

Cart.component.html,当产品被删除时,会在 {{ cart2[i].name }} 处触发错误(“ERROR TypeError: ctx_r1.cart2[i_r4] is undefined”)并且 (click)="删除产品(i)”行:

<form [formGroup]="cartForm2" (ngSubmit)="validateCart()">
  <div
    formArrayName="products"
    *ngFor="let product of cartForm2.controls.products.controls; let i = index"
  >
    <label>{{ cart2[i].name }} : </label>

    <input type="number" [formControlName]="i" />
    <button type="button" (click)="removeProduct(i)">Remove</button>
    <span *ngIf="product.touched && product.hasError('required')">
      The field is required</span
    >
    <span *ngIf="product.touched && product.hasError('min')">
      The field can't be lower than 1</span
    >
  </div>
  <p>cartForm.value : {{ cartForm2.value | json }}</p>
  <div>
  
    <button type="submit" [disabled]="!cartForm2.valid">Validate</button>
  </div>
</form>

cart.component.ts,从服务获取购物车并为购物车中的每个产品创建一个控件。 removeProduct 方法将删除购物车服务中的产品,使用最后的引用更新 cart2 属性,使用良好的索引删除控件:

   cartForm2 = new FormGroup({
      products: new FormArray<FormControl<number>>([]),
    });
    cart2: Product[] = []; 
    ngOnInit(): void {
      this.cart2 = this.cartService.cart;
      this.cart2.forEach(() => {
        this.cartForm2.controls.products.push(
          new FormControl(1, {
            nonNullable: true,
            validators: [Validators.required, Validators.min(1)],
          })
        );
      });
    }
    removeProduct(index: number) {
 this.cartService.deleteProduct(index); 
    this.cart2 = this.cartService.cart
    this.cartForm2.controls.products.removeAt(index);   
    console.log(JSON.stringify(this.cart2));   
    }

cart.service.ts,用于在组件之间存储和共享已购买的产品:

 cart: Product[] = [];

  constructor() {}

  addProduct(product: Product) {
    this.cart.push(product);
  }

  deleteProduct(id: number) {
    this.cart = this.cart.filter((p) => p.id === id);
  }

删除产品后,我得到

ERROR TypeError: ctx_r1.cart2[i_r4] is undefined"

after removing

有什么想法吗?

angular angular-forms
1个回答
0
投票

您从

cart2
数组之前的
controls
中删除,但迭代控件。这意味着,如果模板在这些移除线期间渲染,则
controls
数组将比
cart2
长,但
i
受到控件长度的限制,因此在索引 cart2 时可能会超出范围。

如果您不关心已删除的条目会短暂存在,则可以进行访问

cart2[i]?.name
。由于无论如何控件都将被删除,因此这应该不会显示任何内容并防止越界访问尝试。

您还可以尝试取消您正在使用的“并行数组”。

controls
数组可以转换为
FormGroups
数组,而不是
FormControl
数组,其中每个组都是一个产品,并且所有必需的信息(如
name
)都添加到内部
FormGroups
中。尽管在这样的情况下,这可能不合适,其中
name
(大概)不是表单本身的一部分。

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