Редуктор ngrx не срабатывает после отправленного действия - PullRequest
0 голосов
/ 04 июля 2018

Я обнаружил, что моя функция редуктора не срабатывает, когда я отправляю действие в мой магазин

У меня есть функциональный модуль с действиями, которые отлично работают

У меня проблема с состоянием макета, которое является единственным состоянием, которое я регистрирую в корневом состоянии.

Вот как я инициализирую приложение:

//Root
import * as fromLayout from '../core/store/reducers/layout.reducer';
import * as layoutActions from '../core/store/actions/layout.actions';
import { ActionReducerMap, createSelector } from '@ngrx/store';
import { ActionReducer } from 'ngx-bootstrap/mini-ngrx';
//Interface to hold all states, top level state interface is just a map of keys to inner state types.
export interface Root {
  readonly layout: fromLayout.State
}
export type RootActions =  layoutActions.Actions;

//Get reducers
export const initialState = {
  layout: fromLayout.reducer(undefined, {} as layoutActions.Actions)
}

export interface State {
    root: Root;
  }
//Make sure below is not a function expression
  export function rootReducer(state: Root = initialState, action: RootActions){
    return {
        layout: fromLayout.reducer(state.layout, {} as layoutActions.Actions)
    };
  };

  export const reducers: ActionReducerMap<State> = {
    root: rootReducer
  };

В app.module.ts

  import { reducers } from './reducers/';//This points to -> const reducers: ActionReducer

 StoreModule.forRoot(reducers),
    StoreDevtoolsModule.instrument({maxAge: 25}),
    EffectsModule.forRoot([])

My layout.actions.ts

import { Action } from '@ngrx/store';

export const OPEN_SIDENAV = '[Layout] Open Sidenav';
export const CLOSE_SIDENAV = '[Layout] Close Sidenav';
export const CURRENT_BLOG_ID = '[Layout] Current Blog ID';
export class OpenSidenav implements Action {
  readonly type = OPEN_SIDENAV;
}

export class CloseSidenav implements Action {
  readonly type = CLOSE_SIDENAV;
}

export class CurrentBlogID implements Action {
  readonly type = CURRENT_BLOG_ID;
  constructor(public payload:string){
    console.log(this.payload)
  }
}

export type Actions = OpenSidenav | CloseSidenav | CurrentBlogID;

layout.reducers.ts

import * as layout from '../actions/layout.actions';

export interface State {
  showSidenav: boolean;
  currentBlogID:string
}

const initialState: State = {
  showSidenav: false,
  currentBlogID:''
};

export function reducer(state = initialState, action: layout.Actions): State {
  switch (action.type) {
    case layout.CLOSE_SIDENAV:
      return {
        ...state,
        showSidenav: false,
      };

    case layout.OPEN_SIDENAV:
      return {
        ...state,
        showSidenav: true,
      };
      case layout.CURRENT_BLOG_ID:
      console.log(action.payload)
      return handleCurrentBlogID(state, action)
    default:
      return state;
  }
}

function handleCurrentBlogID(state, action){
  console.log(action.payload)
  let newState = {
    ...state,
    currentBlogID: action.payload,
  }
  return newState
}
export const getShowSidenav = (state: State) => state.showSidenav;

Как я отправляю в магазин:

import { State } from '../../reducers';//This is root state
export class HomeComponent {
  constructor(private store: Store<State>) {}

  onBlogSelected(id){

    this.store.dispatch(new CurrentBlogID(id))
  }
}

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Спасибо @ Хикмат Гурбанлы Я пометил ваш ответ как правильный, но изменил свой код для решения нескольких проблем

Сначала я обнаружил, что приложение, настроенное таким образом с состоянием Root, слишком многословно.

Во-вторых, я нашел это; состояние объекта не было привязано к корневому состоянию, но за его пределами

Root->layout.state
featureState

Код:

export interface State {
    readonly layout: fromLayout.State
}

export const reducers: ActionReducerMap<State> = {
    layout: fromLayout.reducer
};

export const initialState = {
    layout: fromLayout.reducer(undefined, {} as layoutActions.Actions)
}

export const getRoot = (state : State) => state;

export const getBlogsState = createSelector(getRoot, (state : State) => state);

Теперь, когда я захожу в консоль, я получаю

    layout.state
    featureState
0 голосов
/ 04 июля 2018

В rootReducer вы вызываете редуктор макета и передаете его возвращаемое значение, а не функцию. Должно быть как ниже

return {
    layout: fromLayout.reducer
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...