如何将 3 个 reducer 组合成一个 mainReducer 并使用 StoreModule.forFeature() 在 Module 中注册它

How to combine 3 reducers into one mainReducer and register it in Module using StoreModule.forFeature()

我有 3 个对象实现了 3 个不同的接口,我正在使用 ngrx(最新版本)管理它们的状态。 reducer 定义为:loginReducer、PrsnlReducer 和 userReducer。我将 PrsnlReducer 和 userReducer 作为 ngrx 实体处理,因为我想利用 ngrx 实体内置操作,并且我使用基本的 reducer 概念(不作为实体)处理 loginReducer。这是三个:

loginReducer.ts

const initialState: AuthStateInterface = {
    isSubmitting: false,
    user_code: '',
    token: '',
    userId : '',
}
const logReducer = createReducer(
    initialState, 
    on(loginAction, 
    (state: AuthStateInterface): AuthStateInterface => ({
    ...state,
    isSubmitting: true
}))))

export function loginReducers( state: AuthStateInterface, action: Action){
    return logReducer(state, action)
}

userReducer.ts

export interface State extends EntityState<userStateInterface> {
} 
export const adapter: EntityAdapter<userStateInterface> = createEntityAdapter<userStateInterface>();
export const initialState: State = adapter.getInitialState({
}); 
const usrReducer = createReducer(
  initialState,
  on(UserActions.addUser, (state, { user }) => {
    return adapter.addOne(user, state)
  }),
  on(UserActions.setUser, (state, { user }) => {
    return adapter.setOne(user, state)
  })
);
 
export function userReducer(state: State | undefined, action: Action) {
  return usrReducer(state, action);
}

PrsnlReducer.ts

export interface State extends EntityState<prsnlStateInterface > {
  // additional entities state properties
  selectedUserId: number | null;
}
 
export const adapter: EntityAdapter<prsnlStateInterface > = createEntityAdapter<prsnlStateInterface >();
 
export const initialState: State = adapter.getInitialState({
  // additional entity state properties
  selectedUserId: null,
});
 
const persnlReducer = createReducer(
  initialState,
  on(PrsnlActions.addPrsnl, (state, { prsnl }) => {
    return adapter.addOne(prsnl, state)
  })
);

export function prsnlReducer(state: State | undefined, action: Action) {
  return persnlReducer(state, action);
}

现在我想将 3 个 reducer 组合成一个 mainReducer,以便在我的 auth 模块中使用 StoreModule.forFeature() 注册它。因为 ngrx combineReducer 文档太简洁无法提供帮助,所以我在 mainReducer.ts 中所能做的就是如下所示:

mainReducer.ts

import * as fromLogin from 'src/app/auth/store/reducers/loginReducers';
import * as fromPrsnl from 'src/app/auth/store/reducers/prsnlReducer';
import * as fromUser from 'src/app/auth/store/reducers/userReducer';
export interface AuthModuleState {
    login: AuthStateInterface
    prsnl: prsnlStateInterface
    user: userStateInterface
}

export interface State {
    authModule: AuthModuleState;    
}

export const mainReducer = {    
    login: fromLogin,
    prsnl: fromPrsnl,
    user: fromUser
};

export const selectAuthModuleState = createFeatureSelector<AuthModuleState>('authModule');


export const selectLoginState = createSelector(
    selectAuthModuleState, (state: AuthModuleState) => state.login
);

然后我在 authModule 中用

注册 mainReducer.ts

StoreModule.forFeature('auth', mainReducer),

但是 visual studio 错误“没有重载匹配此调用”,如您在屏幕截图中所见:

我如何正确组合这 3 个减速器并将它们注册到模块中以供使用?或者有没有更好的方法来处理这样的目标?我将非常感谢您帮助解决此问题。提前致谢。

根据我的经验,我发现将 3 个减速器注册为单独的功能更容易。

imports: [
  StoreModule.forFeature('login`, fromLogin.reducer),
  StoreModule.forFeature('prsnl`, fromPrsnl.reducer),
  StoreModule.forFeature('user`, fromUser.reducer),
]

如果您喜欢这种模式,您还可以使用新的 createFeature 方法 https://ngrx.io/api/store/createFeature 构建您的 reducers/features

如果您想将 reducer 集中到一个事实来源中,请使用 angular 中可用的 combineReducers()。你可以像这样适应你的情况

export interface AuthModuleState {
    login: any
    prsnl: any
    user: any
}

export const mainReducer:AuthModuleState = {    
    login: fromLogin.loginReducer,
    prsnl: fromPrsnl.prsnlReducer,
    user: fromUser.userReducer
};

const combineReducer = combineReducers(mainReducer)


export function reducer(state:any, action:any){
  return combineReducer(state, action);
}

然后您只需在模块中使用导出的 reducer 就像您已经对 forFeature.

所做的那样

StoreModule.forFeature('auth', reducer),