2017-04-26 51 views
2

我有一個基本的使用ngrx/store的redux實現。Angular 2 - ngrx訂閱在每個狀態更改上運行

//根減速

export const root = { 
    posts: fromPosts.reducer, 
    purchases: fromPurchases.reducer 
} 

export function getAllPosts(state) { 
    return fromPosts.getAll(state.posts); 
} 

export function getAllPurchases(state) { 
    return fromPurchases.getAll(state.purchases); 
} 

在我的組件,我選擇狀態件。

this.posts$ = store.select(getAllPosts).do(c => console.log('posts$ change')); 
this.purchases$ = store.select(getAllPurchases).do(c => console.log('purchases$ change')); 

但是對狀態的每一次改變,兩個處理程序都在運行。例如,當我添加帖子時,purchases$處理程序也會運行。

所有的觀點是隻運行改變的部分,或者我錯了?

回答

0

無論何時將動作分派給商店,它都會傳遞給組合的縮減器並組成新的狀態。然後這個新的狀態被髮射出去。

因此,即使選定的切片狀態未發生變化,您的兩個可觀察值都會看到發射到do運算符的值。

然而,這是簡單的使用distinctUntilChanged運營商改變這種行爲:

import 'rxjs/add/operator/distinctUntilChanged'; 

this.posts$ = store.select(getAllPosts) 
    .distinctUntilChanged() 
    .do(c => console.log('posts$ change')); 

distinctUntilChanged將確保觀察到的只有發射時的價值實際上已經改變,因此,如果國家的您選擇切片具有沒有改變,什麼都不會發射。

+2

這不是真的,因爲在引擎蓋下select方法調用distinctUntilChanged。我也測試過你如何說,而且還是一樣的。 – ng2user

+0

是的,你是對的。如果'select'正在通過你認爲沒有改變的切片,最可能的解釋是你對reducer或選擇器有問題,切片已經發生了變化。我建議使用'scan'或'buffer'運算符來驗證你的狀態是否符合你的期望。 – cartant