You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 09:06:00