繁体   English   中英

Angular NgRx 选择器返回未定义

[英]Angular NgRx Selector returns undefined

这是我的 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:
....

应用程序.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 中的部分)。 我哪里做错了?

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

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

这意味着const appState = (State: AppState) => State; 将返回上面的 object,它没有任何其他属性,除了AppReducer

根据经验,store 的每个属性( slice )都必须与一个 reducer 相关联。 因此,如果您有: StoreModule.forRoot({ a: aReducer, b: bReducer, c: cReducer }) ,您的 state 将如下所示:

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

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

一个快速的解决方法是:

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);
/* ... */

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM