Angular 2:通过引用传递的对象不按预期工作

时间:2017-08-11 17:07:41

标签: angular typescript

之前已将商品添加到购物车中。现在我想更新此现有项的值。在addToCart函数中,findItem()函数检查购物车并返回对现有项的引用。因为该项存在,所以我只是将从findItem()函数返回的现有项分配给newItem,如下所示:existingItem = newItem。我期望已经在购物车中的existingItem现在具有newItem的值,但是当我在购物车中打印商品时,existingItem仍然具有其先前的值,而不是newItem值。

export class CartItem {
  product: Product;
  quantity: number;
  itemTotal: number;
  color: string;
  protectionPlan: string;
}

export class Cart {
  total: number = 0;
  numberOfItems: number = 0;
  items: CartItem[] = [];

  findItem(id: String) : CartItem {
    for(let i=0; i < this.items.length; i++) {
      if(this.items[i].product._id == id) {
        console.log("*************** item found ********************")
        return this.items[i];
      }
    }
    return null;
  }

  addItem(newItem: CartItem) {
    let existingItem: CartItem = this.findItem(newItem.product._id);
    if(existingItem) {
      existingItem = newItem;
      //existingItem.quantity = newItem.quantity;
      console.log("update item id = " + existingItem.product._id);
      console.log("update item quantity = " + existingItem.quantity);
      console.log("update item color = " + existingItem.color);
      console.log("update item protectionPlan = " + 
existingItem.protectionPlan);            
    } else {
      this.items.push(newItem);
      this.numberOfItems++;
    }

    console.log("cart = " + JSON.stringify(this.items));
  }
}

1 个答案:

答案 0 :(得分:1)

这是一个与OOP相关的问题。我试着尽可能清楚地解释:

让我们从这里开始:

addItem(newItem: CartItem) {
    let existingItem: CartItem = this.findItem(newItem.product._id);
    if(existingItem) {
    ...
    }
}

当您输入if块时,您将有两个不同的指针引用两个可能不同的对象。

执行以下操作时:

existingItem = newItem;

您现在有两个引用同一个对象的指针。 所以基本上,做一些事情:

existingItem.quantity = newItem.quantity;

无效,因为您将自己覆盖一个值。

由于您想要改变现有对象的值,一种可能性是使用Object.assign,如下所示:

 if(existingItem) {
    Object.assign(existingItem,newItem);
 }

但在我看来,改变列表的内部状态有点难看。保持您的对象不可变在大多数情况下是好事。所以不同的方法如下:

addItem(newItem: CartItem) {
    let index = //some function that gives you the index in the array where the existing item is, or -1 if not present
    if(index!=-1) {
      items.splice(index,1,newItem); // there is another approach with the .filter operator
      this.items = [...items];// see spread operator
    } else {
      this.items = [...items,newItem]; // see spread operator
      this.numberOfItems++; // this is kinda silly, as items.length would give you this value
    }

}

这样,每次更新或添加元素时,您都会创建新列表

有关不可变性以及如何使用的更多信息(特别是在前端框架中),请查看here!