在 @ngrx/store 4.0 中提供 root reducer
Posted
技术标签:
【中文标题】在 @ngrx/store 4.0 中提供 root reducer【英文标题】:Providing root reducer in @ngrx/store 4.0 【发布时间】:2017-12-26 11:54:29 【问题描述】:在@ngrx/store 2.0 中,我们可以将根reducer 作为一个函数提供,然后我们在应用程序中拆分我们的逻辑。在我更新到@ngrx/store 4.0 之后,我不能再使用这个功能了,我可以看到减速器需要是一个减速器的映射,它将在状态的相同键下创建对象。有没有办法在@ngrx/store 4.0 中使用旧的行为?自己的方式。此外,应用程序被拆分为多个延迟加载的路由,这些路由在某些情况下会重用来自另一个功能的数据。
StoreModule.provideStore(reducer,
auth:
loggedIn: true
)
StoreModule.forRoot(reducers,
initialState:
auth:
loggedIn: true
)
我需要reducers
成为一个获取完整状态并将其分派到正确的reducer 的函数,有没有办法实现这种行为?
【问题讨论】:
【参考方案1】:StoreModule
forRoot()
函数接受 reducerFactory
,可以按如下方式使用:
export function myReducerFactory(reducers: any, initState: any)
return (state = myInitialState, action) => myCustomReducer(state, action);
@NgModule(
// ...
imports: [
StoreModule.forRoot(null, reducerFactory: myReducerFactory )
]
// ...
)
export class AppModule
【讨论】:
【参考方案2】:在我再次查看 ngrx 存储库后,我想通了。为了达到想要的结果,我们需要用新的实现替换 @ngrx/store 减速器工厂。我注入了一个新的减速器工厂,现在应用程序像以前一样工作。简单的代码示例说明如何更换reducer factory吧。
// This factory replaces @ngrx combine reducers so we can manage how we split the keys inside the state
export function combineReducersFactory(
reducers: any,
initialState: any =
): ActionReducer<any, Action>
return function combination(state = initialState, action)
const nextState: any = reducers(state, action);
return nextState !== state ? nextState : state;
;
export const NG_RX_STORE_PROVIDER = [
StoreModule.forRoot(rootReducer, createEmptyState()),
];
export const NG_RX_REDUCER_FACTORY = [
provide: REDUCER_FACTORY,
useFactory: () => combineReducersFactory
];
@NgModule(
imports: [
...NG_RX_STORE_PROVIDER
],
declarations: [...APP_COMPONENTS, ...AG_GRID_COMPONENTS],
providers: [...NG_RX_REDUCER_FACTORY]
)
export class AppModule
【讨论】:
【参考方案3】:您可以设置meta reducer 来接收每个事件并从其根目录操作状态。这是设置它的示例方法:
const myInitialState =
// whatever you want your initial state to be
;
export function myMetaReducer(
reducer: ActionReducer<RootStateType>
): ActionReducer<RootStateType>
return function(state, action)
if (iWantToHandleThisAction)
state = doWhatIWantWith(state);
return reducer(state, action);
;
@NgModule(
imports: [
StoreModule.forRoot(myInitialState, metaReducers: [myMetaReducer] )
]
)
export class AppModule
【讨论】:
myInitialState
未定义且参数肯定错误
将myInitialState
替换为
即可。这个参数不是初始状态,而是ActionReducerMap
。由于在这种情况下,没有任何东西被映射并且所有东西都由元减速器处理,所以它可以工作。
抱歉 - 我的意思是作为您想要作为初始状态传入的任何内容的占位符 - 将进行编辑以使其更清晰。【参考方案4】:
这对我有用:
// your old reducer that handled slicing and dicing the state
export function mainReducer(state = , action: Action)
// ...
return newState;
// new: metaReducer that just calls the main reducer
export function metaReducer(reducer: ActionReducer<AppState>): ActionReducer<AppState>
return function (state, action)
return MainReducer(state, action);
;
// new: MetaReducer for StoreModule.forRoot()
export const metaReducers: MetaReducer<any>[] = [metaReducer];
// modified: app.module.ts
@NgModule(
// ...
imports: [
// neglect first parameter ActionReducerMap, we don't need this
StoreModule.forRoot(,
metaReducers: metaReducers,
initialState: INITIAL_STATE // optional
),
]
)
【讨论】:
以上是关于在 @ngrx/store 4.0 中提供 root reducer的主要内容,如果未能解决你的问题,请参考以下文章