7

在 @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成为一个获取完整状态并将其分派给正确减速器的函数,有没有办法实现这种行为?

4

4 回答 4

4

在我再次查看 ngrx repo 后,我想通了。为了达到想要的结果,我们需要用新的实现替换 @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 {
}
于 2017-07-21T19:21:18.767 回答
2

您可以设置一个元缩减器来接收每个事件并从其根操作状态。这是设置它的示例方法:

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 {}
于 2017-10-05T03:30:14.543 回答
1

StoreModule forRoot()函数接受 a 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 {
}
于 2018-04-30T21:13:49.997 回答
0

这对我有用:

// 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
        }),
    ]
})
于 2017-11-20T15:32:17.907 回答