Angular NgRx选择器返回未定义

问题描述 投票:1回答:1

这是我的app.state.ts

export interface AppState {
  getCards: Card[];
  getFlippedCards: Card[];
  currentPlayer: boolean;
  firstPlayerScore: number;
  secondPlayerScore: number;
  flipped: boolean;
  error: string;
}
export const initialState: AppState = {
  getCards: [],
  getFlippedCards: [],
  currentPlayer: false,
  firstPlayerScore: 0,
  secondPlayerScore: 0,
  flipped: false,
  error: '',
};
const appState = (State: AppState) => State;


export const getCards = createSelector(appState, (state) => state.getCards);
export const getFlippedCards = createSelector(
  appState,
  (state) => state.getFlippedCards
);
export const currentPlayer = createSelector(
  appState,
  (state) => state.currentPlayer
);
export const firstPlayerScore = createSelector(
  appState,
  (state) => state.firstPlayerScore
);
export const secondPlayerScore = createSelector(
  appState,
  (state) => state.secondPlayerScore
);
export const flipped = createSelector(appState, (state) => state.flipped);
export const error = createSelector(appState, (state) => state.error);

app.module.ts:

imports: [
    BrowserModule,
    AppRoutingModule,
    StoreModule.forRoot({ AppReducer }),
  ],

app.reducer.ts

export function AppReducer(state = initialState, action: AppActions): AppState {
  switch (action.type) {
    case ActionTypes.Load:
      return { ...state, getCards: action.payload };
    case ActionTypes.ToggleFlip:
....

app.actions.ts

export enum ActionTypes {
  Load = 'Load Cards',
  ToggleFlip = 'Flip a Card',
}
export class ToggleFlip implements Action {
  readonly type = ActionTypes.ToggleFlip;
  constructor(public payload: Card) {}
}
export class Load implements Action {
  readonly type = ActionTypes.Load;
  constructor(public payload: Card[]) {
    console.log('load app.actions ', payload);
  }
}
export type AppActions = ToggleFlip | Load;

但是,我无法从商店中检索任何信息,this.cards $在选择器中未定义:

app.component.ts

this.store.dispatch(new fromActions.Load(this.cards));
this.cards$ = this.store.pipe(select(fromState.getCards));

商店正好用数组填充。因此,在那里没有问题,我认为我的app.state.ts选择器未正确设置(或者可能是app.module.ts中的部分)。我在哪里做错了?

angular rxjs observable ngrx rxjs6
1个回答
1
投票

通过这样声明您的商店:StoreModule.forRoot({ AppReducer }),据我所知,您的状态对象看起来像这样:

{
 AppReducer: {
   getCards: ...,
   getFlippedCards: ...,
 }
}

意味着const appState = (State: AppState) => State;将返回上述对象,该对象除AppReducer外没有任何其他属性。

根据经验,商店的每个属性(slice)必须与一个reducer相关联。因此,如果您具有:StoreModule.forRoot({ a: aReducer, b: bReducer, c: cReducer }),则您的状态应如下所示:

{
 a: ...,
 b: ...,
 c: ...,
}

我认为整个状态都是馅饼,每个切片都是一个特征。

快速解决方法是:

export interface AppState {
  featureName: {
    getCards: Card[];
    getFlippedCards: Card[];
    currentPlayer: boolean;
    firstPlayerScore: number;
    secondPlayerScore: number;
    flipped: boolean;
    error: string;
  }
}

const featureState = createFeatureSelector<AppState>('featureName');

export const getCards = createSelector(featureState, (state) => state.getCards);
/* ... */
© www.soinside.com 2019 - 2024. All rights reserved.