【问题标题】:Creating an Observable that gets its value from a subscriptions calculation创建一个从订阅计算中获取其值的 Observable
【发布时间】:2019-05-29 07:42:24
【问题描述】:

您好,我正在尝试创建一个 Observable,该 Observable 将具有从另一个订阅发送给它的值,本例是 ngrx Store Reducer

export class IsolatedAgentService {
missionList$: Observable<any>; // I need this observables subscription to emit to calculatedValue$
calculatedValue$:Observable<any>; // I need this observable to get its values from the subscription of  missionList$ subscription
missionList:any;
constructor(
    private _store:Store<any>
){
    this.missionList$ = this._store.select(root_reducers.getMissionList).pipe(skip(1));
    this.missionList$.subscribe((val:any)=> {
        let mostIsolatedCountry:any; //will hold value of calculation
        this.missionList = val;
        mostIsolatedCountry = this.getMostIsolatedCountry(this.missionList);
        // I want tot emit mostIsolatedCountry to another subscription
    });
}

我正在尝试做的事情:

export class IsolatedAgentService {
  missionList$: Observable<any>;
  calculatedValue$:Observable<any> = Observable.create((observer)=>{
    // moved this line here from the previous missionList$ subscription
    let calculated:any = this.getMostIsolatedCountry(this.missionList);
    observer.next(calculated)
  });
  missionList:any;
  calculatedValue:any;
  constructor(
    private _store:Store<any>
  ){
    this.missionList$ = this._store.select(root_reducers.getMissionList).pipe(skip(1));
    this.missionList$.subscribe((val:any)=> {
        let mostIsolatedCountry:any; 
        this.missionList = val;
        this.calculatedValue$.subscribe((value)=>{
            this.calculatedValue = value;
        });
    });
}

目前,我基本上是在一个订阅中设置一个类属性,然后在同一个订阅中,在设置类属性之后,我正在调用第二个订阅,它从该设置的类属性中计算值。

这感觉不对,我确信这不是这样做的方法,但我目前缺乏我的 rxjs/可观察知识。

注意!我对通过 Store Action 发出计算值不感兴趣,我想要一个特定于类实例的 Observable。

【问题讨论】:

  • 你的选择器在reducer里面吗?我相信选择器是一个独立的类,一直在更新状态。这样,您的 observable 将获得更新的订阅值。

标签: rxjs angular6 observable ngrx ngrx-store


【解决方案1】:

这是您问题的答案:

export class IsolatedAgentService {
  missionList$: Observable<Mission[]>;
  calculatedValue$:Observable<any>;
  constructor(
    private _store:Store<any>
  ){
    this.missionList$ = this._store.select(root_reducers.getMissionList).pipe(skip(1));
    this.calculatedValue$ = this.missionList$.pipe( 
      map( missions => this.getMostIsolatedCountry(missions) )
    );
  }
}

甚至

this.calculatedValue$ = this.missionList$.pipe(
    map( this.getMostIsolatedCountry )
);

查看更多关于 NGRX 外墙的信息:https://medium.com/@thomasburleson_11450/ngrx-facades-better-state-management-82a04b9a1e39

为什么你不公开和使用 observables 为什么还要订阅服务?

你应该拥有什么

export class IsolatedAgentService {
  missionList$: Observable<Mission[]>;
  calculatedValue$:Observable<any>;
  constructor(
    private _store:Store<any>
  ){
    this.missionList$ = this._store.select(root_reducers.getMissionList).pipe(skip(1));
    this.calculatedValue$ = this._store.select(root_reducers.getMissionCalculatedValue).pipe(skip(1));
  }
}

还有一个选择器来进行你需要的计算。

export const getMissionCalculatedValue= createSelector(
  getMissionList,
  (missionList) => {
    // do the calculations here
    return calculationResult;
  }
);

【讨论】:

  • 非常感谢这正是我应该做的,我可能会重构我对这个解决方案所做的事情。我最后使用了 BehaviorSubject 来从外部通知订阅者,但这个解决方案更加合理和优雅。
猜你喜欢
  • 2020-08-29
  • 1970-01-01
  • 1970-01-01
  • 2020-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多