我有一系列导入到add-product.component.ts的产品
有一项功能,您可以将产品添加到称为购物篮的购物车中
car.service将要执行的操作是将产品添加到名为basketItems的数组中。如果产品已经存在于basketItems数组中,则它应更改basketItem的该条目。
由于某种原因,购物篮和产品都在变化,这导致原产地商品的价格在只有购物篮的情况下才会发生变化。
我是Angular的新手,我不确定我在add-product.component.html.p
中运行(click)=“ addToCart(product)”时是否传递了该产品的引用Product Page before adding anything to the cart
Product Page after adding something to the cart
add-product.component.html
产品系列
<div class="d-flex justify-content-between flex-wrap">
<div *ngFor='let product of products' class="card mb-5" style="width: 20rem; height: 20rem">
<img style="object-fit: contain; margin-top: 5%" height="45%" src={{product.image}} [title]='product.name' class="card-img-top" alt={{product.name}}>
<div class="card-body">
<div class="mb-3">
<h5 class="card-title">{{product.name}}</h5>
<p class="card-text">{{product.description | slice:0:60}}...</p>
</div>
<a style="float: left" (click)="addToCart(product)" class="card-link text-primary">Add</a>
<p style="float: right">{{product.price | currency}}</p>
</div>
</div>
</div>
<div>
<div>
<table class="table table-striped">
<thead>
<tr>
<th scope="col"></th>
<th scope="col">Count</th>
<th scope="col">Product Name</th>
<th scope="col">Description</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody>
<tr *ngFor='let item of basket; index as itemId'>
<th scope="row"><button (click)="removeFromCart(itemId)">X</button></th>
<th scope="row">{{item.count}}</th>
<td>{{item.name}}</td>
<td>{{item.description | slice:0:20}}</td>
<td>{{item.price | currency}}</td>
</tr>
</tbody>
<thead>
<tr>
<th colspan="3" scope="col"></th>
<th scope="col">Total:</th>
<th scope="col">{{total | currency}}</th>
</tr>
</thead>
</table>
</div>
<button style="float: right" class="btn btn-primary">CHECK OUT</button>
</div>
add-product.component.ts
import { Component, OnInit } from "@angular/core";
import { products } from "../products";
import { CartService } from "../cart.service";
@Component({
selector: "app-add-product",
templateUrl: "./add-product.component.html",
styleUrls: ["./add-product.component.css"]
})
export class AddProductComponent implements OnInit {
// Array of products to be displayed on screen for the user to add to the basket
products: object[] = products;
// The basket is an array of items that were added by the user when they click the add button for that product
basket: object[];
total: number;
constructor(private cartService: CartService) {}
addToCart(item) {
this.cartService.addToCart(item);
this.total = this.basket.reduce((total, item) => total + item.price, 0);
}
removeFromCart(index) {
this.cartService.removeFromCart(index);
this.basket = this.cartService.getItems();
this.total = this.basket.reduce((total, item) => total + item.price, 0);
}
ngOnInit() {
this.basket = this.cartService.getItems();
}
}
cart.service.ts
import { Injectable } from "@angular/core";
import { AngularFirestore } from "@angular/fire/firestore";
@Injectable()
export class CartService {
basketItems: object[] = [];
constructor(private db: AngularFirestore) {}
addToCart(product) {
// if product is already in the basket
// FIX ME basket should mutate and not the product
for (let i = 0; i < this.basketItems.length; i++) {
if (product === this.basketItems[i]) {
let originalPrice =
this.basketItems[i].price / this.basketItems[i].count;
this.basketItems[i].count = this.basketItems[i].count + 1;
this.basketItems[i].price = this.basketItems[i].price + originalPrice;
console.log("this should not mutate ===>", product, "but it does");
return;
}
}
this.basketItems.push(product);
}
removeFromCart(index) {
this.basketItems.splice(index, 1);
}
getItems() {
return this.basketItems;
}
clearCart() {
this.basketItems = [];
return this.basketItems;
}
}
已更新,以提高准确性
答案 0 :(得分:0)
这将返回一个引用:
getItems() {
return this.items;
console.log(this.items);
}
然后您将其分配给您的购物篮:
ngOnInit() {
this.basket = this.cartService.getItems();
}
因此它们都指向相同的参考。当您对购物车服务项目进行更改时,您还需要修改购物篮。
如果您想避免这种行为,可以使用这样的方式
getItems() {
return this.items.slice(0); // or [...this.items] a.k.a create a new instance every time
console.log(this.items);
}
然后进行编辑:
if (product === this.basketItems[i]) { // you check exactly they have same reference
let originalPrice =
this.basketItems[i].price / this.basketItems[i].count;
this.basketItems[i].count = this.basketItems[i].count + 1;
this.basketItems[i].price = this.basketItems[i].price + originalPrice;
console.log("this should not mutate ===>", product, "but it does");
因此,如何修改引用并不重要。他们都被修改了。
因此,您正在往返跳动相同的对象。 您需要做的是:
this.basketItems.push({...product}); // insert new object everytime
// and checking part should be
if (product.id === this.basketItems[i].id) // they are not same object anymore you can not check reference equality.