【问题标题】:BehaviourSubject is emitting value only onceBehaviorSubject 只发出一次值
【发布时间】:2018-11-18 05:19:36
【问题描述】:

我正在学习 rxjs,我想我做错了什么,因为我的 BehaviourSubject 只发出一次值。

在我的服务中 -

private cartItemCount = new BehaviorSubject<Observable<Number>>(this.getCartItemsCount());
actualCartItemCount=this.cartItemCount.getValue();

getCartItemsCount(){
return this.http.get<Number>('/api/getCartItemsCount/'+this.getCartID());
}

Below Method 也在上述添加或删除产品的服务中,但将从 ProductCartComponent 调用,并且在内部我调用 Behavior Subject 的下一个方法

private updateProductCart(cartID:string,productId:number,change:string){
this.cartItemCount.next(this.getCartItemsCount());
return this.http.get<Item>('api/updateProductItem/'+cartID+'/'+productId+'/'+change);
}

现在在我的 NavBar 组件中,我订阅了 actualCartItemCount Observable

constructor( private cartService:ShopingCartService)
 { }

ngOnInit() {
this.cartService.actualCartItemCount.
subscribe(res => {this.totalCartItemCount = res;
}

在控制台中,我可以看到 getCartItemsCount 会在添加或删除发生时被调用,但在我订阅了 actualCartItemCount 的 NavBar 组件中只会被调用一次。

请指导我,如果需要更多详细信息,请告诉我...

【问题讨论】:

  • 我猜你有两个不同的服务实例。向我们展示您提供服务的方式和地点(即您在哪里拥有providers: [ShopingCartService]
  • 在 app.module.ts 我有以下数组,所有的服务都是这样提到的 - providers: [SignUpService, ShopingCartService, AuthGuard, LoginGuard,{提供:HTTP_INTERCEPTORS, useClass:AuthInterceptor, multi:true }],
  • 您可能正在破坏subscription 的某个地方,例如ngDestroy 或其他地方,以至于它没有得到
  • this.cartItemCount.getValue() 你有来自this.getCartItemsCount() 的返回值,它只创建一次。那么订阅this.cartService.actualCartItemCount 就是订阅this.http.get 而不是BehaviorSubject
  • 是的@martin,你是对的...我不能在 this.cartItemCount 上使用 .asObservable,因为它已经是 Observable所以我继续这样做..

标签: angular rxjs behaviorsubject


【解决方案1】:

首先,仔细阅读component interaction guide

如果 NavBar 始终在视图中,则不需要 BehaviorSubject,只需简单的 Subject 即可。

import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs';

@Injectable()
export class CartService {

  // Observable number sources
  private countSource = new Subject<number>();

  // Observable number streams
  count = this.countSource.asObservable();

  // Service message commands
  updateCount(count: number) {
    this.countSource.next(count);
  }
}

在 NavBar 中,您可以使用 async 管道直接在模板中使用 observable:

@Component({
  selector: 'app-nav-bar',
  template: `Count : {{cartService.count | async}}`
})
export class NavBarComponent {
  constructor(private cartService: CartService) {}
  }

在产品购物车中,您可以更新新的计数,如下所示,它会更新 NavBar 或任何其他地方的值:

@Component({
  selector: 'app-product-cart',
  template: `
  `
})
export class ProductCartComponent {
  constructor(private cartService: CartService) {}
  /**
  Update count in the shared service and thus in NavBar
  */
  private updateCartCount(count: number){
     this.cartService.updateCount(count);
  }
  }

【讨论】:

  • 我想在导航栏中更新购物车中商品的数量,因为导航栏和产品购物车组件不是相关组件,每当从购物车中添加或删除任何产品时,我都需要在它们之间进行交互.
  • 您希望产品购物车将count 发送到导航栏?或者只是告诉 navbar 发生了一些变化,以便 NavBar 可以从服务器获取新数据?
  • 我希望产品购物车向 NavBar 计数发送 +1 或 -1,以防分别从购物车中添加或删除产品。但是我被困在那里,所以使用上述任何更新的方法从服务器获取计数数据。我想我需要更多关于共享信息 b/w 组件的知识。
  • 我已经完成了,但没有从 countSource 创建额外的 Observable count 并进行了一些其他更改!!! 最终查询- 我打开了 2 个选项卡,其中 1 个选项卡中的更改没有反映在其他选项卡中。我们有什么办法让它发挥作用吗??
猜你喜欢
  • 2020-03-15
  • 1970-01-01
  • 2021-08-11
  • 1970-01-01
  • 1970-01-01
  • 2019-12-14
  • 1970-01-01
  • 1970-01-01
  • 2020-09-07
相关资源
最近更新 更多