分派动作后ngrx reducer无法启动

时间:2018-07-04 14:35:41

标签: angular ngrx

我发现向商店发送动作时,我的reducer函数不会触发

我有一个功能正常的功能模块

我遇到的问题是布局状态,这是我在根状态下注册的唯一状态。

这是我初始化应用程序的方式:

//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([])

我的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 :(得分:1)

rootReducer中,您正在调用布局简化程序,并传递其返回值本身不起作用。应该是下面的样子

return {
    layout: fromLayout.reducer
};

答案 1 :(得分:0)

感谢@Hikmat Gurbanli 我已将您的答案标记为正确,但更改了我的代码以解决几个问题

首先,我实际上发现以Root状态设置应用有点冗长。

第二,我发现了这一点;功能状态不是附加到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