【问题标题】:Using RxJS combineLatest to filter observables?使用 RxJS combineLatest 过滤 observables?
【发布时间】:2019-03-03 19:12:33
【问题描述】:

我正在查看是否可以在 Angular 服务中使用 combineLatest 来删除 activeFiler$ 开关块(该服务应该做同样的事情)。这是组件design right now (stackblitz link),我正在尝试删除除render$ observable 之外的所有属性:

export class TodosComponent implements OnInit {
  constructor(private ts:TodoService) {}
  render$: Observable<Todo[]>; 
  activeFilter$: Observable<VISIBILITY_FILTER>;


ngOnInit() {
  this.render$ = this.ts.selectedTodos$;
  this.activeFilter$ = this.ts.activeFilter$;

  this.activeFilter$.subscribe(active=>{
        switch (active) {
    case VISIBILITY_FILTER.SHOW_COMPLETED:
      this.render$ = this.ts.completeTodos$;
      break;
    case VISIBILITY_FILTER.SHOW_ACTIVE:
      this.render$ = this.ts.incompleteTodos$;
      break;
    default:
      this.render$ = this.ts.todos$;
      }
  });
}
  }
}

如图所示,我已将 this.render$ 初始化为从 todo.service.ts 文件返回的 Observable。该方法如下所示:

  this.selectedTodos$ = 
  combineLatest(this.activeFilter$, this.completeTodos$, this.incompleteTodos$, this.todos$, this.applyFilter);

  private applyFilter(filter, completeTodos, incompleteTodos, todos): Todo[] {
    switch (filter) {
      case VISIBILITY_FILTER.SHOW_COMPLETED:
        return completeTodos;
      case VISIBILITY_FILTER.SHOW_ACTIVE:
        return incompleteTodos;
      default:
        return todos;
    }
  }

所以,有了这一切,我想我应该能够删除 todos 组件中的 this.ts.ostore.observe(ACTIVE_FILTER_KEY).subscribe(active=>{ 块,但如果我删除了整个应用程序将停止工作。

一个奇怪的事情是,如果我注释掉$activeFilter 订阅,并记录下来:

  this.render$ = this.ts.selectedTodos$;
  this.render$.subscribe(v=>console.log(v));

当我输入更多待办事项时,它们会被记录下来,但它们不会呈现......有什么想法吗?

【问题讨论】:

  • completeLatest 是什么?
  • ngOnInit 中的代码不是正确的 RxJS。更改 this.render$ 对订阅者没有影响。我认为您真正需要的是 switchMap。
  • @edwin 我认为问题是combineLatest 不会发出任何东西,直到所有被观察到的Subject 实例发出至少一个值。在我的情况下,我使用它来过滤 COMPLETEINCOMPLETEALL,但 COMPLETE 主题永远不会发出任何值,因此它永远不会触发,combineLatest 只是坐在那里等待它。我正在更新 store 实现以在构造时发出一个空数组,以便保证 combineLatests 来自每个 Observable 的值。

标签: angular typescript rxjs stackblitz


【解决方案1】:

我让它工作了。

使其工作的核心部分是combineLatest 在每个Observable 至少发射一次时发射。

在我的例子中,执行通知的ReplaySubject&lt;Todo[]&gt; 实例在EStore 初始化时没有执行通知,因此ReplaySubject&lt;Todo[]&gt;s 永远无法触发combinedLatest 运算符。

我更改了 EStore 实现,使其不发出任何内容或 EStore 初始化时使用的实体,现在它可以工作了……非常好。

   changeDetection: ChangeDetectionStrategy.OnPush

有效。我们不需要事件发射器或@Input 来工作。只需查询商店并让它发挥作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-27
    • 1970-01-01
    • 2017-03-05
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-06
    相关资源
    最近更新 更多