シーズンIDに基づいてAPIからフィクスチャ、結果などをレンダリングするアプリがあります-このIDはSeasonStateのプロパティとして状態に保存されます:
export interface SeasonsState extends EntityState<Season> {
allSeasonsLoaded: boolean;
currentlySelectedSeasonId: number;
}
これは、APIからフェッチして状態に保存するフィクスチャ、結果などを決定するために他のコンポーネントによって使用されます。例えば:
this.store
.pipe(
select(selectCurrentlySelectedSeason)
).subscribe(seasonId => {
this.store.dispatch(new AllFixturesBySeasonRequested({seasonId}));
this.fixtures$ = this.store
.pipe(
select(selectAllFixturesFromSeason(seasonId))
);
});
これはうまく機能しますが、私が本当に望んでいるのは、特定のシーズンのフィクスチャがまだ状態に保存されていない状態で、フィクスチャのみをフェッチできるようにすることです。
エフェクトでAPIからデータを条件付きでロードするために使用するセレクターを作成しようとしました。
export const selectSeasonsLoaded = (seasonId: any) => createSelector(
selectFixturesState,
fixturesState => fixturesState.seasonsLoaded.find(seasonId)
);
しかし、これを実装する方法/これが正しいアプローチであるかどうかはわかりません。
編集:以下の回答からの情報を使用して、私は次の効果を書きました、しかしコメントを見てください-私は私のwithLatestFromのペイロードからseasonIdを使用できる必要があります。
@Effect()
loadFixturesBySeason$ = this.actions$
.pipe(
ofType<AllFixturesBySeasonRequested>(FixtureActionTypes.AllFixturesBySeasonRequested),
withLatestFrom(this.store.select(selectAllFixtures)), // needs to be bySeasonId
switchMap(([action, fixtures]) => {
if (fixtures.length) {
return [];
}
return this.fixtureService.getFixturesBySeason(action.payload.seasonId);
}),
map(fixtures => new AllFixturesBySeasonLoaded({fixtures}))
);
エフェクトを次のように設定します[私はngrx6を使用しているので、ngrx6でテストしました。他のバージョンを使用している場合は、アイデアを得て、それに応じてコードを調整します]-
@Effect() allFixturesBySeasonRequested: Observable<Action> =
this._actions$
.pipe(
//Please use your action here;
ofType(actions.AllFixturesBySeasonRequested),
//please adjust your action payload here as per your code
//bottom line is to map your dispatched action to the action's payload
map(action => action.payload ),
switchMap(seasonId => {
//first get the fixtures for the seasonId from the store
//check its value if there are fixtures for the specified seasonId
//then dont fetch it from the server; If NO fixtures then fetch the same from the server
return this.store
.pipe(
select(selectAllFixturesFromSeason(seasonId)),
//this will ensure not to trigger this again when you update the fixtures in your store after fetching from the backend.
take(1),
mergeMap(fixtures => {
//check here if fixtures has something OR have your logic to know
//if fixtures are there
//I am assuming it is an array
if (fixtures && fixtures.lenght) {
//here you can either return NO action or return an action
//which informs that fixtures already there
//or send action as per your app logic
return [];
} else {
//NO fixtures in the store for seasonId; get it from there server
return this.http.get(/*your URL to get the fixtures from the backend*/)=
.pipe(
mergeMap(res => {
return [new YourFixtureFetchedSucccess()];
}
)
)
}
})
);
})
)
次に、指定したseasonIdのフィクスチャをサービス/コンポーネントまたはアプリの設計方法からフェッチするアクションをディスパッチする必要があります。
それがあなたにアイデアを与え、あなたの問題を解決するのに役立つことを願っています。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加