2016-12-05 28 views
0

我在Angular 2應用程序中使用了@ ngrx/effects,並且我試圖實現一個依賴於基於條件的效果的問題應用程序的狀態。如何在@ ngrx/effects上觀察Observable效果

在我的狀態下,我有一個位置 - >功能的地圖,以locationId(以及其他位置的地圖 - > *)爲鍵。當ACTION_A發生時,我只希望在有當前位置的最新功能時繼續。當ACTION_A被派遣時,能力可能已經是最新的,但是,應用程序也可能正在加載新的。

與下面的代碼,一旦ACTION_A被分派一次,isOutOfDate被稱爲每任何行動被分派到店時間。所以,即使在滿足最新的過濾器之後,它仍然是活躍的。但是,如果將getCapabilities替換爲getCapabilitiesWorking,那麼只有在調度ACTION_A動作時纔會調用isOutOfDate,直到滿足篩選條件爲止,正如我期望從任一實現中那樣。

所以,它看起來像我的思念與如何combineLatestfiltertake作品東西...

或許我接近這一切都錯了...

我寧願能夠使用我的'當前位置'選擇器的常用功能

任何想法?

@Effect() route$ = actions$ 
    .ofType(ACTION_A) 
    .switchMap(() => this._store.let(getCapabilities) 
     .filter(capabilities => !isOutOfDate(capabilities)) 
     .take(1) 
    ) 
    .map(do some stuff); 

// Selector function that causes excess observable emits 
export const getCapabilities = 
    compose(fromLocations.currentLocationLookup(fromLocations.getCapabilities), fromRoot.getLocations); 

// Selector function works as expected 
export const getCapabilitiesWorking = function (state$: Observable<AppState>): Observable<Capability> { 
    return state$ 
     .let(fromRoot.getLocations) 
     .map(l => l.capabilitiesByLocation[l.currentId]); 
}; 

// fromLocations 
// ------------- 

export function getCapabilities(state$: Observable<LocationsState>): Observable<{ [id: string]: Capability }> { 
    return state$.map(s => s.capabilitiesByLocation); 
} 

// Find the value in 'collection' corresponding to the current location 
export function currentLocationLookup<T>(
    collection: (state$: Observable<LocationsState>) => Observable<{ [id: string]: T }> 
): (state$: Observable<LocationsState>) => Observable<T> { 
    return (state$: Observable<LocationsState>): Observable<T> => { 
     return Observable.combineLatest(
      state$.let(getCurrentLocation), 
      state$.let(collection), 
      (locId, map) => map[locId] 
     ); 
    }; 
} 

編輯:爲了澄清,該isOutOfDate功能不斷得到調用,但是「做一些東西」不...

回答

1

嘗試使用withLatestFrom方法。你的效果可以像

@Effect() route$ = actions$ 
.ofType(ACTION_A) 
.withLatestFrom(this._store.let(getCapabilities)) 
.filter(([action, capabilities]) =>!isOutOfDate(capabilities)) 
.map(do some stuff); 
+1

我認爲這種可能性,但是,它不是我所需要的。它將採取商店中當前的價值,這可能尚未填充。然後過濾器在錯誤的位置被應用。我需要它等待,直到功能被填充,然後有效果「做一些事情」 –

1

withLatestFrom將無法​​正常工作,因爲觀察到的結果只會發出的輸出,當源發射(行動派),按照文檔需要combineLast,所以:

@Effect() route$ = actions$ 
    .ofType(ACTION_A) 
    .combineLatest(this._store.let(getCapabilities)) 
    .filter(([action, capabilities]) =>!isOutOfDate(capabilities)) 
    .map(do some stuff); 
0

你可以嘗試用skipWhile

,以取代在switchMap的過濾器,這樣效果會:

@Effect() route$ = actions$ 
.ofType(ACTION_A) 
.switchMap(() => this._store.let(getCapabilities) 
    .skipWhile(capabilities => !isOutOfDate(capabilities)) 
    .take(1) 
) 
.map(do some stuff); 

這幫了我一個類似的用例:)