首页 文章

在@ngrx / store 4.0中提供root reducer

提问于
浏览
6

在@ngrx / store 2.0中,我们可以将根reducer作为函数提供,然后我们在应用程序中拆分逻辑 . 在我更新到@ngrx / store 4.0后,我无法再使用此功能,我可以看到reducers需要是reducers的映射,它将在状态下的相同键下创建对象 . 有没有办法在@ngrx / store 4.0中使用旧的行为在我的状态中,组件知道另一个,我需要能够动态分割我的状态,我还需要能够将动作分配到我的正确的reducer中自己的方式 . app也被分成多个延迟加载的路由,在某些情况下重用来自另一个功能的数据 .

StoreModule.provideStore(reducer, {
      auth: {
        loggedIn: true
      }
    })

StoreModule.forRoot(reducers, {
      initialState: {
        auth: {
          loggedIn: true
        }
      }
    })

我需要 reducers 成为一个获取完整状态并将其发送到正确的reducer的函数,有没有办法实现这种行为?

4 回答

  • 0

    在我第二次看了ngrx repo后,我发现了它 . 为了达到理想的效果,我们需要用新的实现替换@ ngrx / store reducer工厂 . 我注入了一个新的减速机工厂,现在应用程序像以前一样工作 . 关于如何更换减速机工厂的简单代码示例吧 .

    // 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 {
    }
    
  • 4

    您可以设置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 {}
    
  • 2

    这对我有用:

    // 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
            }),
        ]
    })
    
  • 0

    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 {
    }
    

相关问题