2016-12-06 8 views
0

私は、ngrxストアアプローチを使用して状態を管理するangular2アプリケーションに取り組んでいます。アプリはgithubのhere戻り値に基づいて観測値をマージすることに関する混乱

問題文でオープンソースであり、私はこのアプローチに直面しています

具体的な問題は、他の観察可能なリターンがをゼロに観察1から放射された値を使用しています。

私は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; 
} 

は今、私は trip-detail.component.tsで特定の旅行を得ることができ、私の基本減速 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]; 
}); 

です私はルートlocalhost:4200/trips/2をリロードする場合は、この

selectedTrip$: Trip; 

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

のように今、そして私たちの店は

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または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); 
} 

希望はあなたに役立ちます。

関連する問題