Angular跨路由共享Service数据不更新,如何用Observable实现购物车同步
解决步骤
1. 修改data.service.ts,引入RxJS响应式数据流
使用BehaviorSubject存储购物车数据,它会给新订阅者主动推送当前最新值,保证进入购物车页面时也能拿到已添加的商品,同时封装操作方法避免外部直接修改数据源。
import { Injectable } from "@angular/core"; import { Product } from "./product"; import { BehaviorSubject, Observable } from 'rxjs'; // 用providedIn: root确保全局只有一个服务实例,是数据同步的前提 @Injectable({ providedIn: 'root' }) export class DataService{ // 预设商品数据不变,无需改响应式 productsData:Array<Product>=[ {name:'Tomato',total:10, url:'https://migrostvstr.blob.core.windows.net/migrostv/2021/08/domates-kg-c7462d-1650x1650-1.jpg'}, {name:'Patato',total:27, url:'https://migros-dali-storage-prod.global.ssl.fastly.net/sanalmarket/product/28303000/patlican-kemer-kg-2ac52c-1650x1650.jpg'}, {name:'Garlic',total:20, url:'https://migros-dali-storage-prod.global.ssl.fastly.net/sanalmarket/product/28293383/28293383-874ca9-1650x1650.jpg'} ]; // 私有Subject不对外暴露,防止外部随意修改 private productCartSubject = new BehaviorSubject<Product[]>([]); // 对外暴露只读的可观察对象,供组件订阅更新 productCart$: Observable<Product[]> = this.productCartSubject.asObservable(); constructor(){} // 封装添加购物车逻辑 addToCart(product: Product): void { const currentCart = this.productCartSubject.value; // 可选逻辑:同个商品累加数量,不需要可直接push const existItem = currentCart.find(item => item.name === product.name); if(existItem) { existItem.total += 1; } else { // 解构赋值避免对象引用问题 currentCart.push({...product}); } // 发送新值触发所有订阅组件更新 this.productCartSubject.next([...currentCart]); } }
2. 修改products.component.ts,补全添加逻辑
import { Component, OnInit } from '@angular/core'; import { DataService } from '../data.service'; import { Product } from '../product'; @Component({ selector: 'app-products', templateUrl: './products.component.html', styleUrls: ['./products.component.css'] }) export class ProductsComponent implements OnInit { // 给模板绑定用的商品列表 productsData: Product[] = []; constructor(private data:DataService) { } ngOnInit() { this.productsData = this.data.productsData; } getItems(value: Product){ // 调用服务方法添加到购物车 this.data.addToCart(value); } }
3. 修改products.component.html,修正遍历数据源
你原代码中newData未定义,替换为组件中声明的productsData即可:
<div class="products"> <div class="product-cards" *ngFor="let items of productsData"> <img class="icons" src="{{items.url}}"> <div class="items-style"> <div> Ürün ismi: {{items.name}} </div> <div> Ürün adedi: {{items.total}} </div> <a class="add-icon"><i class="fas fa-cart-plus fa-2x icon"(click)="getItems(items)" ></i></a> </div> </div> </div>
4. 修改product-cart.component.ts,订阅购物车更新
import { Component, OnInit } from '@angular/core'; import { Product} from '../product'; import { DataService } from '../data.service'; @Component({ selector: 'app-product-cart', templateUrl: './product-cart.component.html', styleUrls: ['./product-cart.component.css'] }) export class ProductCartComponent implements OnInit { // 渲染用的购物车列表 cartList: Product[] = []; constructor(private datacart:DataService) { } ngOnInit (){ // 订阅购物车数据变化,实时更新本地列表 this.datacart.productCart$.subscribe(cart => { this.cartList = cart; console.log(this.cartList); }) } }
之后你可以在product-cart.component.html中直接遍历cartList渲染已添加的商品即可。
注意:如果你没有在服务中设置
providedIn: 'root',需要手动在AppModule的providers数组中添加DataService,确保全局只有一个服务实例,否则不同路由拿到的服务实例独立,数据依然无法同步。
内容的提问来源于stack exchange,提问作者Tarik
相关产品推荐
相关产品推荐

