2016-10-07 136 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