typescript - 获取结账(购物车)页面中产品的总价(Angular 7)
我想获取并显示客户在购物车页面添加的商品总价。
目标:客户应该能够观察订单总价的变化。问题是客户可以增加或减少数量。
我有一个从会话存储中获取的“OrderLine”对象数组。每个对象都有 quantity 和 priceWhenBought。
@SessionStorage({key: 'cart'}) orderLineMealsInCart: Array<OrderLine> = [];
这里是 OrderLine 类:
export class OrderLine {
mealId?: number;
meal?: Meal;
orderId?: number;
quantity: number;
priceWhenBought: number;
}
在 HTML 文件中有一个输入框,用于实时控制商品数量,并且有一个方法绑定到该输入框,当你输入不同的数字后,该方法会将“旧”数量的商品更改为修改后的数量。
<div *ngFor="let orderLineMeal of orderLineMealsInCart">
<div class="cartMealsSection">
<div *ngFor="let meal of mealsForImage">
<div *ngIf="meal.id === orderLineMeal.mealId">
<img src="{{meal.picture}}" alt="" class="cartMeal-picture">
</div>
</div>
<div>{{orderLineMeal.mealId}}</div>
<div>{{orderLineMeal.priceWhenBought}}</div>
<div>{{orderLineMeal.quantity}}</div>
<div>{{orderLineMeal.quantity * orderLineMeal.priceWhenBought}}</div>
</div>
<div>
<div>
<button (click)="deleteOrderLineMealFromCart(orderLineMeal)">Delete</button>
</div>
<div>
<mat-form-field>
<input type="number" matInput [(ngModel)]="orderLineMeal.quantity" (ngModelChange)="changeOrderLineMeal(orderLineMeal)">
</mat-form-field>
</div>
</div>
然后是更改数量的方法:
changeOrderLineMeal(orderLineMeal: OrderLine) {
const index = this.orderLineMealsInCart.indexOf(orderLineMeal);
this.orderLineMealsInCart[index] = orderLineMeal;
(<any>this.orderLineMealsInCart).save(); // <- saving to the session storage
}
我知道为了实时变化订单的总价我需要 Observable(rxjs),但在这种情况下,我完全不知道该如何实现。
我还将在这里放置订单类,你可以在其中找到订单的总价,这是我需要实现的最后一件事。
export class Order {
id?: number;
mobilenumber: string;
customerName: string;
pickUpDateAndTime?: Date;
orderedDateAndTime?: Date;
comment: string;
orderLines?: OrderLine[];
totalPrice: number;
}
我会对任何形式的帮助心存感激。
答案#1
你只需要用 reduce 计算总数。你可以使用一个 getter
get total()
{
return this.items.reduce((sum,x)=>
({quantity:1,
priceWhenBought:sum.priceWhenBought+x.quantity*x.priceWhenBought}),
{quantity:1,priceWhenBought:0}).priceWhenBought;
}
//In your .html
{{total}}
简要说明 关于使用 getter 的唯一原因是你可以在 HTML 中引用一个变量,例如
{{myvariable}}
如果你使用 getter。那是一个以 get 开头的函数,显示函数的结果
{{myget}}
get myget()
{
return "Hello word";
}
关于 reduce:
reduce 有三个参数。这三个参数必须与数组的类型相同。所以如果我们的数组是对象数组,那么三个参数也必须是相同类型。第一个参数是“累加器”,第二个参数是数组的元素,第三个参数是“初始值”。“转换”元素的类型也必须相同
所以,如果我们的数组是一个数字数组,我们可以做
[1,4,7,2].reduce((sum,x,0)=>(sum+x))
如果我们有一个这样的元素数组
this.total2=[
{x:1},
{x:4},
{x:7},
{x:2}
].reduce((sum,x)=>({x:sum.x+x.x})) //total2 will be{x:14}
请注意,它是通过 reduce((
this.total2=[
{x:1,y:3},
{x:4,y:4},
{x:7,y:5},
{x:2,y:6}
].reduce((sum,x)=>({x:sum.x+x.x,y:sum.y+x.y})) //return {x:14,y:18}
再次注意,"result" 必须是一个具有属性 x 和 y 的对象。如果你不向 reduce 提供第三个参数,reduce 会取数组的第一个元素并对其余元素进行迭代。这就是为什么如果我们做类似的操作时会出现这种情况
this.total2=[
{x:2,y:3},
{x:4,y:4},
{x:7,y:5},
{x:2,y:6}
].reduce((sum,x)=>({x:sum.x+x.x*x.y,y:1})) //return {x:65,y:1}
//return 2+4*4+7*5+2*6 ¡¡at first sum={x:2,y:3}, but not use the "y"
//to calculate the product: is NOT 2*3
//So, we need add the third argument
.reduce((sum,x)=>({x:sum.x+x.x*x.y,y:1}),{x:0,y:0})
