关于如何在应用状态下组合reducers / data的问题:
数据示例(Firebase):
{
"artists" : {
"168dgYui7ExaU612eooDF1" : {
"name" : "Brand New",
"id" : "168dgYui7ExaU612eooDF1",
}
},
"genres" : {
"popPunk" : {
"name" : "pop punk"
},
"screamo" : {
"name" : "screamo"
}
},
"genresPerArtist" : {
"168dgYui7ExaU612eooDF1" : {
"popPunk" : true,
"screamo" : true
}
}
}
应用状态:
export type State = { app: AppState };
export type AppState = { genres: IGenre[], artistGenres: IGenre[], artists: any[], currentArtist: any };
export const initialState: State = {
app: {
artists: [],
currentArtist: null,
genres: [],
artistGenres: []
}
}
减速器:
export function appReducer(state: AppState, action: GenreActions.Actions): AppState {
// TODO: add reducers for Fetch Artist and Fetch Artists
switch (action.type) {
case GenreActions.FETCH_GENRES: {
return { ...state };
}
case GenreActions.FETCH_GENRES_SUCCESS: {
return { ...state, genres: action.payload };
}
case GenreActions.FETCH_ARTIST_GENRES: {
return { ...state };
}
case GenreActions.FETCH_ARTIST_GENRES_SUCCESS: {
return { ...state, artistGenres: action.payload };
}
default: {
return state;
}
}
}
效果:
@Effect()
FetchGenres$: Observable<Action> = this.actions$
.ofType(appActions.FETCH_GENRES)
.switchMap(() => {
return this.firebaseProvider.genres
.map(payload => new appActions.FetchGenresSuccess(payload))
.catch(() => of(new appActions.FetchGenresSuccess([])));
});
// TODO: See if I should be using store's genres here, or if that should be combined elsewhere
@Effect()
FetchArtistGenres$: Observable<Action> = this.actions$
.ofType(appActions.FETCH_ARTIST_GENRES)
.map((action: appActions.FetchArtistGenres) => { return action.payload })
.switchMap((artistId: string) => {
return this.firebaseProvider.genresByArtist(artistId)
.withLatestFrom(this.store.select(state => state.app.genres))
.map((results) => {
let artistGenres = results[0];
let genres = results[1];
return genres.filter(genre => {
let result = artistGenres.findIndex(g => g.$key === genre.$key);
return (result ? true : false);
});
})
.map(payload => new appActions.FetchArtistGenresSuccess(payload));
});
Firebase 提供者:
@Injectable()
export class FirebaseProvider {
genres: FirebaseListObservable<IGenre[]>;
constructor(
private db: AngularFireDatabase
) {
this.genres = this.db.list('/genres');
}
genresByArtist(artistId: string): Observable<IDictionary[]> {
return this.db.list(`/genresPerArtist/${artistId}`);
}
}
艺术家页面:
我的问题是你应该如何在 NGRX4 中组合不同的数据切片?
示例:我有一个艺术家详细信息页面。在该页面中,我想显示艺术家信息以及艺术家的流派。在其他地方,我可能有一个艺术家列表页面,其中显示了多个艺术家及其流派。我在哪里获取和合并我的应用程序中的所有相关信息?在减速机?在效果上(FetchArtistGenres$ 目前是如何做到的)?
其他问题:我不认为我希望在我的应用程序状态中拥有整个“genresPerArtist”或“artists”节点,因为它最终会变得非常大而且我不确定它是否会表现出色(如果我错了在这里,这就是要走的路,让我知道)。相反,我会在需要时获取特定的 Artists 流派节点(/genresPerArtist/${artistId}
)