原文链接:https://medium.com/youngers-consulting/ngrx-tips-part-1-module-setup-with-lazy-loading-5dc8994b5a2d

如果您的Angular项目针对延迟加载进行了调整,并使用按需加载的独立模块进行加载,这些模块通过`StoreModule.forFeature(…) 定义了自己的 state 片段,您可以像这样定义根模块:

StoreModule.forRoot({} as any, { initialState: getInitialState })

但是,在我们使用所有状态初始化应用程序时,我们不提供任何 reducer。 这种方法的问题是,如果 reducer 不可用,那么任何尚未加载的功能将在操作分派时从状态中删除。

例如,假设我们的应用程序有一个“settings”区域和一个“Todos”区域,如果我们最初加载应用程序的“Todos”区域而不访问“settings”,该状态的一部分将在第一个操作分派时被移除,因为还没有可用的reducer来处理该功能的状态:

settings removed

由于settings功能尚未加载,因此settings部分被删除。

防止这种情况的一种方法(不影响应用程序中的所有reducer)是,首先对所有功能设置一个默认reducer,该reducer只取得当前状态并返回:

import { ActionReducerMap } from '@ngrx/store';

import * as settings from './settings/settings.actions';
import * as todos from './todos/todos.actions';

export interface ApplicationState {
    settings: settings.SettingsState;
    todos: todos.TodosState;
}

export function defaultReducer<T>(state: T){ return state; }

export const initailReducerMap = {
    settings: defaultReducer,
    todos: defaultReducer,
} as ActionReducerMap<ApplicationState>;

export function getInitailState() {
    return {
        settings: settings.initialState,
        todos: todos.initialState,
    } as ApplicationState;
}

然后如下更新NgRx初始化:

StoreModule.forRoot(initialReducerMap, { initialState: getInitialState })

随着您的功能模块被加载,它们将替换默认的 reducer。 在此之前,他们会在任何派发的操作上返回初始状态,以防止这些功能从状态移除:

settings removed

“settings” 现在被保留

随着您的继续开发,如果添加新功能并更新了ApplicationState接口,它应该会导致编译错误,直到initialReducerMap更新。

然后,您的store选择器可以安全地假定功能状态部分将始终存在,而无需执行未定义(undefined)的检查。

在下一篇文章中,我将详细介绍选择器和测试。