2016-10-07 27 views
0

我想基于路由参数,以获得特定项目,例如,{ key: "321" },从ngrx/store。我得到它的工作是这样的:拼合可观察到的

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"}, ...]填充随着时间的推移。

我想知道有没有更好/不同的方式来做到这一点?

此外,为什么我会在.take(1)之前获得相同的项目倍数(state.items.length)倍?

+0

你想从你们店里的物品数组提取多个项目?如果是这样的话,你的代码可以被优化。 – KwintenP

+0

@KwintenP我需要通过特定属性的值从列表中获取项目。例如,对于url“/ items/123”,值为** 123 **,属性为**键**。 – Sasxa

回答

1

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

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

+0

是的,功能是一样的,但你的方式可能会更有效率,因为mergeMap()将可观察数组转换为可观察数组,而map +过滤工作在纯数组上* ... – Sasxa

+0

MergeMap并不真正做什么你描述,除非我错了。 MergeMap将对observable中的每个元素执行一个函数。这个函数的结果应该是一个由mergeMap操作符展开的observable。 – KwintenP