2015-11-03 36 views
1

我有一個RxJS主題,用於發佈對集合的更改。每次收集更改時,主題都會將新內容作爲數組發佈。例如。有效創建可觀察對象,以從可觀察集合中篩選特定項目

let collectionSubject = new Rx.BehaviourSubject(); 

collectionSubject.onNext([{ 
    id: 1 
}]); 

我想提供客戶端代碼在'按ID'的基礎上訂閱此集合的功能。例如。當集合更改時,它們只會收到與查詢ID匹配的項目(如果存在)。如果該項目不存在或剛剛被刪除,則它們會收到未定義的項目。

我天真地實現這個如下:

byId(id) { 
    return collectionSubject.filter(items => items.find(item => item.id == id)); 
} 

然而,這將創建一個新的觀察到的每一次,並導致項目陣列的多個冗餘迭代。我可以使用一個由ID鍵控的Map來爲特定的ID緩存observables,但是這仍然會導致對不同id的items數組進行多次迭代。

我能看到的唯一解決方案是編寫大量自定義機制來爲每個ID創建和緩存和銷燬主題,在發生更改時迭代集合一次,並將每個項目發佈到任何相應的主題。

有沒有更簡單,更習慣的方式來實現這一點,使用底層的RxJS操作符?關鍵要求是一次只迭代基礎集合。

+0

比照發射陣列內容項的特技http://xgrommx.github.io/rx-book/content/observable/observable_instance_methods/groupby.html – user3743222

回答

1

不確定傳遞的鏈接是否會將您引導至實際的解決方案,因此我在此提供有關可能方法的更多詳細信息。這個想法是使用運營商groupBy,比較。 https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/groupby.md,http://reactivex.io/documentation/operators/groupby.html爲彈子,如果你喜歡這裏的測試規格https://github.com/ReactiveX/RxJS/blob/master/spec/operators/groupBy-spec.js)。

假如你有通過ID映射一個旁聽者,稱爲observers,你可以嘗試的東西沿着線:

collectionSubject = new Rx.Subject(); 
observers = [0, emits("observer for group 1"), emits("observer for group 2")]; 

collectionSubject 
    .concatMap(function (arr) {return arr;}) 
    .tap(emits("tap")) 
    .groupBy(function (item) {return item.id;}) 
    .subscribe(function (groupObs) { 
       groupObs.subscribe(function (item) { 
        observers[item.id](item); 
       }); 
       }); 

collectionSubject.onNext([ 
    {id : 1, value : "first item/group 1"}, 
    {id : 1, value : "second item/group 1"}, 
    {id : 2, value : "first item/group 2"}, 
    {id : 2, value : "second item/group 2"}, 
    {id : 1, value : "third item/group 1"}, 
    {id : 2, value : "third item/group 2"}, 
]); 

測試結果在這裏:這裏

"tap emits first item/group 1" 
"observer for group 1 emits first item/group 1" 
"tap emits second item/group 1" 
"observer for group 1 emits second item/group 1" 
"tap emits first item/group 2" 
"observer for group 2 emits first item/group 2" 
"tap emits second item/group 2" 
"observer for group 2 emits second item/group 2" 
"tap emits third item/group 1" 
"observer for group 1 emits third item/group 1" 
"tap emits third item/group 2" 
"observer for group 2 emits third item/group 2" 

jsbin。 https://jsbin.com/qikamamohi/edit?js,console

注:

  • concatMap是由項目並且爲了