【问题标题】:Update display for items in shopping cart with Subject/Observable使用 Subject/Observable 更新购物车中商品的显示
【发布时间】:2019-05-02 21:06:03
【问题描述】:

我正在创建一个应用程序,用户可以在其中将商品添加到他们的购物车中,然后它会在本地存储中跟踪这些商品。当用户单击一个组件中的添加按钮时,我需要导航栏实时更新项目数量,但我无法使用事件发射器来设置我的应用程序。

我正在寻找的功能很简单,当我添加一个项目并将其放入本地存储时,我的导航栏中购物车徽标旁边的数字应该增加 1。我知道这可以使用 Observables 和科目,我只是很难理解它。我已经将代码从组件移动到服务开始,因为我认为这将允许两个组件与其通信。我可以使用该服务将项目正确地添加到本地存储中,但在那之后我陷入了困境,我需要跟踪服务中添加的项目数量。

这里是服务:

@Injectable({
  providedIn: 'root'
})
export class MenuService {
  public apiRoot: string = `http://localhost:3000`;
  orders;

  constructor(private http: HttpClient) { }

  order(id, name, options, price) {
    //confirm the order is correct
    const orderConfirmed = confirm("Add this item to your cart?");

    if (orderConfirmed) {
    let order = new Order(id, name, options, price)   

    //get and set any existing orders from local storage or set to a blank array if there are none
    this.orders = localStorage.getItem('order') ? JSON.parse(localStorage.getItem('order')) : [];

    //push to our orders array
    this.orders.push(order)

    //store in localStorage
    localStorage.setItem('order', JSON.stringify(this.orders)) 
    }
  }

然后这是我的 navbar.ts:

export class NavbarComponent implements OnInit {
  itemsInCart;
  constructor() { }

  getItemsInCart() {
    this.itemsInCart = JSON.parse(localStorage.getItem('order'))
  }

  ngOnInit() {
    this.getItemsInCart();
  }

}

现在我只是直接从本地存储中提取项目并显示它们,但显然如果我要添加其他项目,这将无法实时工作,基本上我想制作我的导航栏组件,它位于router-outlet 能够订阅MenuService 中的this.orders 属性,以便在用户将商品添加到购物车时实时跟踪this.orders 的长度。抱歉,如果这看起来很明显,仍在学习中!

【问题讨论】:

    标签: angular observable subject


    【解决方案1】:

    为您的服务添加一个主题,在您的订购方法中调用它并在您的组件中订阅它

    storage.service.ts

    orders
    ordersChanged = new Subject<any>()
    
    order(){
       //your code
       this.ordersChanged.next(this.orders)
        }
    

    component.ts

    itemsInCart
    
    constructor(private storageService: StorageService){}
    
    ngOnInit(){
       this.storageService.ordersChanged.subscribe(items => itemsInCart = items)
    }
    

    【讨论】:

    • 这太棒了,它帮助我在搞砸了一些之后更好地理解了主题,而且我还能够通过在另一个组件中订阅相同的主题来确保价格得到更新,非常有帮助。非常感谢@RadekF!
    【解决方案2】:

    当您关闭浏览器选项卡或刷新数据被破坏时,请勿在内存中使用 localstorage 存储,(专家级别您应该​​使用 Ngrx 存储)

    检查不相关的组件:与服务共享数据here

    storage.service.ts

    export class StorageService {
      private foo: String;
      public fooChanged$: EventEmitter<any>; // For Communication between components
      constructor() {
        this.fooChanged$ = new EventEmitter(); // For Communication between components 
      }
    
      public emitFooChange(): void {// For Communication between components
        this.fooChanged$.emit();
      }
    
      setFoo(data: String) {
        this.foo = data;
      }
    
      getFoo(): Number {
        return this.foo;
      }
    }
    

    component.ts

    constructor(private storageService: StorageService){}
    ngOnInit(){
      this.storageService.setFoo("Foo");
      console.log('foo', this.storageService.getFoo());
    }
    

    【讨论】:

      【解决方案3】:

      我希望您使用的是 Angular 框架,服务遵循单例模式,因此该属性也只有一个实例。 (无需使用可观察模式。)

      使用属性 cart_items_count 创建一个服务,在构造函数中将值(从本地存储中提取的实际计数)分配给属性。当您添加到购物车时,cart_items_count 也会增加 1。

      【讨论】:

        猜你喜欢
        • 2021-11-27
        • 2014-07-03
        • 1970-01-01
        • 2015-07-03
        • 1970-01-01
        • 1970-01-01
        • 2017-11-05
        • 2015-06-01
        • 1970-01-01
        相关资源
        最近更新 更多