Я добавил интерфейс OrderItem, чтобы немного упростить чтение:
export interface OrderItem {
product: IProduct;
quantity: number;
}
Я обновил CartService для использования BehaviorSubject и держал orderItems как наблюдаемый, и изменил getItems для возврата наблюдаемый. Также измените addItem, чтобы обновить наблюдаемое:
export class CartService {
private subject = new BehaviorSubject<OrderItem[]>([]);
private orderItems$: Observable<OrderItem[]> = this.subject.asObservable();
constructor() {
}
getItems(): Observable<OrderItem[]>{
return this.orderItems$;
}
addItem(orderItem: OrderItem) {
const orderItems = this.subject.getValue();
const productIndex = orderItems.findIndex(item => item.product._id === orderItem.product._id);
if(productIndex >= 0){
const updatedOrderItem = orderItems[productIndex];
updatedOrderItem.quantity +=1;
const newOrderItems = orderItems.slice(0);
newOrderItems[productIndex] = {
...orderItems[productIndex],
...updatedOrderItem
}
} else {
orderItems.push(orderItem)
}
this.subject.next(orderItems);
}
В компоненте корзины, просто возвращая наблюдаемое в сервисе:
export class CartComponent implements OnInit {
myOrderItems$: Observable<OrderItem[]>;
constructor(private cartService: CartService) { }
ngOnInit() {
this.myOrderItems$ = this.cartService.getItems();
}
}
В HTML, простой ngFor и Asyn c pipe:
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of myOrderItems$ | async">
<td>{{item.product.name}}</td>
<td>{{item.product.price | currency : 'GBP'}}</td>
<td>{{item.quantity}}</td>
<td>{{item.quantity * item.product.price | currency : 'GBP'}}</td>
</tr>
</tbody>
</table>
и в качестве простого теста в app.component:
export class AppComponent implements OnInit {
name = 'Angular';
constructor(private cartService: CartService){}
ngOnInit(){
this.addProduct1();
}
addProduct1(){
let product1: IProduct = {_id:1, name: 'Product 1', price:25.00};
let orderItem: OrderItem = { product: product1, quantity:1};
this.cartService.addItem(orderItem);
}
addProduct2(){
let product: IProduct = {_id:2, name: 'Product 2', price:15.00};
let orderItem: OrderItem = { product: product, quantity:1};
this.cartService.addItem(orderItem);
}
}
и HTML:
<app-cart></app-cart>
<button (click)="addProduct1()">Add Product 1</button>
<button (click)="addProduct2()">Add Product 2</button>
Я создал рабочий пример для stackblitz: https://stackblitz.com/edit/angular-rxjs-shopping-cart-example