FireStore + NGRX + Entités

voix
0

Je suis aux prises avec NGRX + Firestore. J'utilise un code tutoriel pour mon application et tout fonctionne parfaitement. Le problème vient quand je veux ajouter une autre action « requête » à mes actions CRUD. J'ai tout mis en place (la nouvelle action et le nouvel effet) mais je ne sais pas quoi faire avec le réducteur et le public contests: Observable<Icontest[]> = this.contestStore.select(_fromcontest.selectAll);bit.

Mon objectif est d'avoir une requête qui obtient tous les documents, et une autre requête qui ne reçoit que les documents qui correspondent à un critère (requête filtré).

une partie de contest.actions.ts

export const QUERY = '[contest] query contests';
export const QUERY_MINE = '[contest] query my contests';

[...]

// Initial Query
export class Query implements Action {
  readonly type = QUERY;
  constructor() {}
}

// Query only my contests
export class QueryMine implements Action {
  readonly type = QUERY_MINE;
  constructor() {}
}
[...]

export type contestActions =
  Query | QueryMine | Added | Modified | Removed | Update | Create | Delete | CreateSuccess | UpdateSuccess | DeleteSuccess | Failure ;
...

une partie de contest.effect.ts

@Effect()
  query$: Observable<Action> = this.actions$.ofType(contestActions.QUERY).pipe(
    switchMap(action => {
      return this.afs.collection<IContest>('contests').stateChanges();
    }),
    mergeMap((actions: DocumentChangeAction[]) =>  actions),
    map( (action: DocumentChangeAction) => {
      return {
        type: `[contest] ${action.type}`,
        payload: {
          id: action.payload.doc.id,
          ...action.payload.doc.data()
        }
      };
    })
  );

  @Effect()
  queryMine$: Observable<Action> = this.actions$.ofType(contestActions.QUERY_MINE).pipe(
    switchMap(action => {
      return this.afs.collection<Icontest>('contests', ref => {
        return ref.where('owner', '==', this._auth.cachedUser.uid);
      }).stateChanges();
    }),
    mergeMap((actions: DocumentChangeAction[]) =>  actions),
    map( (action: DocumentChangeAction) => {
      return {
        type: `[contest] ${action.type}`,
        payload: {
          id: action.payload.doc.id,
          ...action.payload.doc.data()
        }
      };
    })
  );
...

et contest.reducer.ts est:

export const contestAdapter = createEntityAdapter<IContest>();
export interface State extends EntityState<IContest> { }
export const initialState: State = contestAdapter.getInitialState();

export function contestReducer(
  state: State = initialState,
  action: actions.contestActions) {

    switch (action.type) {

      case actions.ADDED:
        return contestAdapter.addOne(action.payload, state);

      case actions.MODIFIED:
        return contestAdapter.updateOne( {
          id: action.payload.id,
          changes: action.payload,
        }, state);

      case actions.REMOVED:
      return contestAdapter.removeOne(action.payload.id, state);


      default:
      return state;
    }
  }

      // Create the default selectors
      export const getContestState = createFeatureSelector<State>('contests');

      export const {
        selectIds,
        selectEntities,
        selectAll,
        selectTotal,
      } = contestAdapter.getSelectors(getContestState);

Pour obtenir tous les documents, je l' appelle contestStore.dispatch( new _contestActions.Query())et obtenir que mes documents que j'appelle contestStore.dispatch( new _contestActions.QueryMine()) Cependant, comment puis - je attribuer les résultats de chaque requête à une variable différente, disons:

  • public contests: Observable<Icontest[]> = this.contestStore.select(_fromcontest.selectAll );
  • public mycontests: Observable<Icontest[]> = this.contestStore.select( ????? ); ?

S'il vous plaît aider!

Créé 12/12/2017 à 23:09
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
1

Votre demande effet $ chargera toutes les entités. Donc, vous n'avez pas besoin d'une nouvelle action de recherche, mais vous avez besoin d'un nouveau sélecteur.

Pour créer un nouveau sélecteur, vous devez créer un espace dans l'état pour stocker l'uid qui peut être référencé.

export interface State extends EntityState<IContest> {
  currentUserUid: string;
}

et une nouvelle action:

export const LOGIN = '[contest] login';

export class Login implements Action {
  readonly type = LOGIN;
  constructor(public payload: string) {}
}

nouveau cas de réducteur:

case actions.LOGIN:
  return { ...state, currentUserUid: action.payload };

nouveau sélecteur:

export const getCurrentUserUid = createSelector(
  getContestState,
  state => state.currentUserUid
);

export const getMine = createSelector(
  selectAll,
  getCurrentUserUid,
  (contests, currentUserUid) =>
    contests.filter(contest => contest.owner === currentUserUid)
);

usage:

Expédition l'action de connexion lorsque vous vous connectez.

public mycontests: Observable<Icontest[]> = this.contestStore.select(_fromcontest.getMine);

ps. Je recommande la création d' un AuthStore.

Créé 14/12/2017 à 21:25
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more