在Angular 5中,当组件在另一个组件中包含两次时,如何防止组件调用其订阅两次?

在Angular 5中,当组件在另一个组件中包含两次时,如何防止组件调用其订阅两次?,angular,typescript,Angular,Typescript,在Angular 5中,当组件在另一个组件中包含两次时,如何防止组件调用其订阅两次? 例如,我有一个NavMenuComponent,在模板中,我有一个包含两次的购物车 <!-- cart 1 in nav fixed --> <nav-menu-cart class="toolbar-item" *ngIf="auth.isAuthenticated()"></nav-menu-cart> <!-- cart

在Angular 5中,当组件在另一个组件中包含两次时,如何防止组件调用其订阅两次? 例如,我有一个NavMenuComponent,在模板中,我有一个包含两次的购物车

        <!-- cart 1 in nav fixed -->
    <nav-menu-cart class="toolbar-item" *ngIf="auth.isAuthenticated()"></nav-menu-cart>


        <!-- cart 2 in nav scrolled -->
    <nav-menu-cart class="toolbar-item" *ngIf="auth.isAuthenticated()"></nav-menu-cart>
saveCartWithNewItem最终调用CartService.saveCart(购物车)

问题是saveCartWithNewItem函数被调用两次,而它只需要调用一次。(下面的日志屏幕截图显示其已被调用两次)

有人可能会问,为什么NavMenuCartComponent负责调用saveCartWithNewItem?为什么不让数据包含在CartService中,而只是在订阅中刷新NavMenuCartComponent中的数据呢?原因是CartService此时只负责HTTP调用,而不负责存储数据

另外,最初负责调用可观察对象的组件是ProductsGridComponent。它使用连接器服务CartConnectorService


从根本上说,我希望实现的是,我希望允许ProductsGridComponent允许向购物车添加项目。而且,假设NavMenuComponent有两个NavMenuCartComponent,我需要在这些组件以及持久层(通过服务)中更新数据。我的实现是使用CartConnectorService来确保这一点,但现在我遇到了重复调用问题。感谢您的帮助

我能想到的简单解决方案:

if (!this.subscription) {
  this.subscription = cartConnectorService.cartItemAdded$.subscribe(
    newCartItem => {
      console.log("in cartConnectorService.cartItemAdded$.subscribe");
      this.saveCartWithNewItem(newCartItem);
    });
}

您可以在
NavMenuCartComponent
上创建一个
@Input
,告诉它是否
saveCartWithNewItem

NavMenuCartComponent
中:

@Input callSaveCart: boolean;

//...

ngOnInit() {
    // ...

    if(callSaveCart) {
        this.subscription = cartConnectorService.cartItemAdded$.subscribe(newCartItem => {
            console.log("in cartConnectorService.cartItemAdded$.subscribe");
            this.saveCartWithNewItem(newCartItem);
        });
    }
}
然后,在HTML中指定要保存的内容:

     <!-- cart 2 in nav scrolled -->
     <nav-menu-cart class="toolbar-item" [callSaveCart]="true" ngIf="auth.isAuthenticated()"></nav-menu-cart>


我能看到的唯一方法是在组件上创建一个
@Input
,指定是否调用
saveCartWithNewItem
,以便告诉其中一个保存而不是另一个。感觉有点混乱。你能提供一些代码来支持这种可能性吗?这不起作用,ctor被调用两次,并且订阅直到低于你的条件才被设置,因此这个.subscription.unsubscripte();永远不会发生。我刚测试过这个,几乎可以用了。所以我投了更高的票。现在唯一的问题是navMenuCart组件具有navMenuCart:ICart={buyerId:'',items:[]};这实际上需要在保存后更新,这里有什么想法吗?通过上面提到的更新,只有一个模板的数据得到更新。@joey如果两个组件需要共享状态,则共享状态属于服务。我感谢您的帮助。我会考虑一下,因为这会改变很多事情。非常感谢。
     <!-- cart 2 in nav scrolled -->
     <nav-menu-cart class="toolbar-item" [callSaveCart]="true" ngIf="auth.isAuthenticated()"></nav-menu-cart>