NGRX 4:如何组合来自多个来源的数据

时间:2017-11-08 17:02:30

标签: firebase ngrx ngrx-store-4.0

关于如何在app状态下组合reducer / 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中组合不同的数据片段?

示例:我有一个Artist Detail页面。在该页面中,我想要显示艺术家信息以及艺术家的类型。在其他地方,我可能会有一个艺术家列表页面,其中我展示了多个艺术家及其流派。我在哪里获取并合并我的应用程序中的所有相关信息?在减速机?在效果(FetchArtistGenres $目前如何做)?

其他问题:我不认为我想拥有整个&#34; genresPerArtist&#34;或&#34;艺术家&#34;在我的应用状态中的节点,因为它最终会变得非常大并且我不确定它是否具有高性能(如果我在这里错了,那就是要走的路,请告诉我) 。相反,我在需要时获取特定的Artists流派节点(/genresPerArtist/${artistId}

0 个答案:

没有答案