.push()将对象添加到数组中会更新该数组中的其他类似对象

时间:2019-11-08 13:44:15

标签: angular typescript

一个奇怪的问题:

在我的DOM中,我生成一个可单击的列表。在单击时,将以单击的对象作为参数调用一个函数,然后将该对象赋予一个ID,并将其推入数组。问题是所有相似的对象都将获得其ID,其他任何值也将更新。这意味着如果我两次单击Object1,数组中的两个对象都将被更新。

DOM:

<div class="col-3" *ngFor="let product of consolidatedProducts" (click)="selectProduct(product)">
  <div class="productSearchCard">
    <div class="name">
      {{product.name}}
    </div>
    <div class="price">
      {{product.price}} {{product.currency}} 
      <span *ngIf="product.unit">
        {{product.unit.short}}
      </span>
    </div>
    <div class="description">
      {{product.description}}
    </div>                                    
  </div>
</div>

组件

public selectProduct(product: any) {
  const id = new Date().getTime();
  product.id = id;
  this.selectedProducts.push({
    id,
    component: product
  });
}

在进行推送之后,即使对象ID中的ID不同,数组中的所有对象在产品中的ID也相同。参见下面的输出:

[
  0: {
    component: {
      id: 1573220848440
      name: "Set of sticker"
      price: "9"
      quantity: "1"
      sub-category: "Sticker"
      unit: {long: "piece", short: "p."}
    },
    id: 1573220848274
  },
  1: {
    component: {
      id: 1573220848440
      name: "Set of sticker Swiss Realty"
      price: "9"
      quantity: "1"
      sub-category: "Sticker"
      unit: {long: "piece", short: "p."}
    },
    id: 1573220848440
  }
]

复制到这里: https://stackblitz.com/edit/angular-1bhaqn

1 个答案:

答案 0 :(得分:2)

问题是您在运行selectProduct(product)时总是引用内存中的同一对象。您需要先对对象进行深拷贝,然后再为其分配新值,然后将新对象推入数组。

public selectProduct(product: any) {
    // MAKE DEEP COPY OF OBJECT (THERE ARE OTHER WAYS TO DO THIS ALSO)
    const newProduct = JSON.parse(JSON.stringify(product));
    const id = new Date().getTime();
    newProduct.id = id;
    this.selectedProducts.push({
      id,
      component: newProduct
    });
    console.log(this.selectedProducts);
  }
  

https://stackblitz.com/edit/angular-rjxor4