簡體   English   中英

關於基於可觀察變量的歸並的混淆

[英]Confusion regarding observables merging based on their return

我正在開發一個使用ngrx存儲方法來管理狀態的angular2應用程序。 應用程序是開源GitHub上這里

問題陳述

我用這種方法面臨的特定問題是,當其他可觀察值返回null時,使用從一個可觀察值發出的值

當我的ngrx 存儲中存在數據時,我不想查詢后端api


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 ,那么我們的商店將初始化為initialState,如下所示

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

和下面的方法將無法正常工作,因為getTrips和getSelectedTripId將為null

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或未定義。

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

如果您需要在顯示組件之前准備好數據,則可以使用解析器。 在這里查看此答案。

在您的情況下,它將看起來如下所示,並且如果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);
}

希望這對您有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM