0

关于如何在应用状态下组合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}

4

0 回答 0