2016-12-06 70 views
0

我正在使用ngrx存儲方法來管理狀態的angular2應用程序。應用在GitHub上的開源here關於基於回報的可觀察性合併的困惑

我用這種方法面臨的問題陳述

具體的問題是,當其他可觀察返回null利用一個可觀察發射值。

我不想查詢後端API時,我有我的NGRX 目前的數據。


Angular2代碼

下面是我的trips.reducer.ts文件

export interface State { 
    ids: string[]; 
    trips: { [id: string]: Trip }; 
    selectedTripId: string; 
} 

const initialState = { 
    ids: [], 
    trips: {}, 
    selectedTripId: null 
} 

export function reducer(state = initialState, action: Action): State {} 

export function getTrips(state : State) { 
    return state.trips; 
} 

export function getTripIds(state: State) { 
    return state.ids; 
} 

export function getSelectedTripId(state: State) { 
    return state.selectedTripId; 
} 

下面是我的基地減速index.ts

export interface State { 
    trips: fromTripsReducer.State;  
} 

const reducers = { 
    trips: fromTripsReducer.reducer, 
} 

export function getTripsState(state: State): fromTripsReducer.State { 
    return state.trips; 
} 

export const getTrips = createSelector(getTripsState, fromTripsReducer.getTrips); 
export const getTripIds = createSelector(getTripsState, fromTripsReducer.getTripIds); 
export const getSelectedTripId = createSelector(getTripsState, fromTripsReducer.getSelectedTripId); 
export const getSelectedCityId = createSelector(getTripsState, fromTripsReducer.getSelectedCityId); 

export const getTripsCollection = createSelector(getTrips, getTripIds, (trips, ids) => { 
    return ids.map(id => trips[id]); 
}); 

export const getSelectedTrip = createSelector(getTrips, getSelectedTripId, (trips, id) => { 
    return trips[id]; 
}); 

現在,我可以得到trip-detail.component.ts特定行程這樣

selectedTrip$: Trip; 

constructor(private store: Store<fromRoot.State>) { 
    this.selectedTrip$ = this.store.select(fromRoot.getSelectedTrip); 
} 

現在,如果我重新加載路線localhost:4200/trips/2,那麼我們的商店將初始化爲初始化狀態時顯示如下

const initialState = { 
    ids: [], 
    trips: {}, 
    selectedTripId: null 
} 

及以下方法將不作爲getTrips工作,getSelectedTripId將爲空

export const getSelectedTrip = createSelector(getTrips, getSelectedTripId, (trips, id) => { 
    return trips[id]; 
}); 

所以,現在我可以做一個後端請求,它只會加載基於url id的單行程,像這樣

return this.http.get(`${this.apiLink}/trips/${trip_id}.json` 
    .map((data) => data.json()) 

,但我想使後端的要求,只有當行是不存在的存儲和

this.selectedTrip $返回null或undefined。

this.selectedTrip$ = this.store.select(fromRoot.getSelectedTrip); 

回答

0

如果您需要在顯示組件之前準備好數據,則可以使用解析器。看到這個答案here

在你的情況下,它會看起來如下,解析器只會確保數據的加載被初始化,如果selectedTripnull。注意:因爲我們不會在任何地方使用解析器的返回數據,所以我們可以返回任何東西。

@Injectable() 
export class SelectedTripResolver implements Resolve { 

constructor(
    private store: Store 
) {} 

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { 

    // get the selectedTrip 
    return this.store.select(fromRoot.getSelectedTrip) 
     // check if data is ready. If not trigger loading actions 
     .map((selectedTrip) => { 
      if (selectedTrip === null) { 
       //trigger action for loading trips & selectedTrip 
       this.store.dispatch(new LoadTripAction()); 
       this.store.dispatch(new LoadselectedTripAction()); 
       return false; // just return anything 
      } else { 
       return true; // just return anything 
      } 
     }); 

}

這裏解析器將確保當selectedTrip數據還沒有準備好負荷的動作被觸發。

trip-detail.component中,您只需要等待有效數據。像這樣:

constructor(private store: Store<fromRoot.State>) { 
    this.selectedTrip$ = this.store.select(fromRoot.getSelectedTrip) 
     .filter(selectedTrip => selectedTrip !== null); 
} 

希望這是有道理的,並幫助你。