2016-12-06 98 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); 
} 

希望这是有道理的,并帮助你。