展平一个 Observable

Flatten an Observable

我正在尝试从 ngrx/store 获取特定的 Item,例如 { key: "321" }基于路由参数。我是这样工作的:

this.route.params
  .map((params: any) => params.key)

  .mergeMap((key: string) => {

    return this.store.select(state => state.items)

      .mergeMap((items: Observable<any[]>) => items)

      // .do(item => console.log(item, key))

      .filter((item: any) => item.key === key);
  })
  .take(1)
  .subscribe(console.log);

其中 state.items 是一个对象数组,例如:[ {key: "1"}, {key: "2"}, ...] 随着时间的推移而填充。

我想知道是否有 better/different 方法来做到这一点?

此外,为什么我在 .take(1) 之前得到了多次 (state.items.length) 次相同的商品?

代码已经很不错了,但是内部的 mergeMap 不是必需的。如果我理解正确的话,过滤器实际上应该是一张地图。您将在 store.select 语句中获得一组项目,并且在您的过滤器中一次处理一个项目。这不应该工作,因为它是你正在处理的数组。使用地图,我们可以获得项目数组作为输入,return 项目实际上就是我们正在寻找的项目。

this.route.params
  .map((params: any) => params.key)
  .mergeMap((key: string) => {
      return this.store.select(state => state.items)

         // no need for this mergeMap
         //.mergeMap((items: Observable<any[]>) => items)

         // map will actually get an array of items as input here
         // we want to get the element from the array matching 
         // the key from the route param and return the first element
         // => [0] since there should be only one
         .map((item: any[]) => items.filter((item) => item.key === key)[0];
})
.take(1)
.subscribe(console.log);

带有模拟工作示例的 Jsbin:http://jsbin.com/sihina/7/edit?js,console