Как вложить состояния лениво загружаемых функциональных модулей с @ ngrx / store и @ ngrx / entity?

Я уже 2 дня изо всех сил пытался составить состояния модуля featureA («сценарии») и вложенного модуля featureB («намерения»).

Вот желаемая структура моего состояния (структура 1):

{
  authentication: { ... },
  router: { ... },
  scenarios: {
    resources: { ids: { ... }, entities: { ... } },
    intents: {
      resources: { ids: { ... }, entities: { ... } }
    }
  }
}

Я бы тоже был доволен (структура 2):

{
  authentication: { ... },
  router: { ... },
  scenarios: { ids: { ... }, entities: { ... } },
  intents: { ids: { ... }, entities: { ... } },
}

Хотя это не отражает структуру моих модулей.

Проблема со структурой 1 заключается в том, что scenarios/reducers/index.ts предоставляет ActionReducerMap, scenarios/modules/intents/reducers/index.ts также предоставляет ActionReducerMap, и я не знаю, как их составить. Все, что я пробовал, даже не компилируется из-за конфликтов типов.

Проблема со структурой 2 заключается в том, что intents часть состояния продолжает выпадать из состояния из-за того, что IntentsModule не загружается при загрузке первой страницы и другие редукторы приложения выполняют свою работу.

Вот код:

/scenarios/scenarios.module.ts:

import { reducers, getInitialState } from './reducers';

@NgModule({
  imports: [
    ...,

    ScenariosRoutingModule,

    StoreModule.forFeature('scenarios', reducers, { initialState: getInitialState }),
    EffectsModule.forFeature([ScenariosEffects]),
  ],
})
export class ScenariosModule {}

/scenarios/reducers/index.ts:

import * as fromRoot from '../../../app.reducers';
import * as fromScenarios from './scenarios.reducers';
import * as fromIntents from '../modules/intents/reducers';

export interface ScenariosState {
  resources: fromScenarios.State;
  intents: fromIntents.IntentsState;
}

export interface State extends fromRoot.State {
  scenarios: ScenariosState;
}

export const reducers: ActionReducerMap<ScenariosState> = {
  resources: fromScenarios.reducer,
  intents: fromIntents.reducers, <-- This is the part with types conflicts
};

/scenarios/modules/intents/intents.module:

import { reducers, getInitialState } from './reducers';

@NgModule({
  imports: [
    ...,

    IntentsRoutingModule,

    StoreModule.forFeature('intents', reducers, { initialState: getInitialState }), <-- Also this part seems to add 'intents' as a top-level property of state
    EffectsModule.forFeature([IntentsEffects]),
  ],
})
export class IntentsModule {}

/scenarios/modules/intents/reducers/index.ts:

import * as fromIntents from './intents.reducers';

export interface IntentsState {
  resources: fromIntents.State;
}

export interface State {
  intents: IntentsState;
}

export const reducers: ActionReducerMap<IntentsState> = {
  resources: fromIntents.reducer,
};

export function getInitialState(): IntentsState {
  return {
    resources: fromIntents.initialState,
  };
}

person paztek    schedule 09.08.2018    source источник


Ответы (2)


  • import и export structure 2 IntentsModule в корне AppModule.
  • import ScenariosModule после IntentsModule в корне AppModule.

Не вкладывайте различные IntentsModules под ScenariosModules. Вместо этого создайте разделение и максимально сгладьте структуру вашего проекта, этого по сути требует structure 2.

Я обнаружил, что хороший подход для большинства ситуаций, за исключением функций, связанных с Auth, - это создание двух модулей для каждой функции, которые будут лениво загружаться вместе, но при этом управление состоянием отделено от пользовательского интерфейса, но эти соответствующие модули должны совместно использовать API такая же форма, то есть:

  • (FrameworkLayoutModule и FrameworkStoreModule) и (AuthModule).

Впоследствии повторно используемые функции могут быть лениво загружены с помощью SecureModule или PublicModule по мере необходимости.

person ebduhon    schedule 10.08.2018
comment
Мой ScenariosModule загружается в AppRoutingModule с loadChildren: './modules/scenarios/scenarios.module#ScenariosModule'. My IntentsModule загружается ScenariosRoutingModule с loadChildren: './modules/intents/intents.module#IntentsModule'. Можете ли вы указать мне на несколько хороших ресурсов, предлагающих ваш подход с двумя модулями на функцию? Спасибо. - person paztek; 10.08.2018

Эта проблема с использованием хранилища намерений в двух модулях. И NgRx не может дважды создать хранилище намерений.

решение 1

удалите «намерения» из сценариев.module или из intents.module, если они там не используются.

решение 2

переместить хранилище намерений в StoreModule.forRoot или в родительский модуль сценариев и намерений.

person Kliment Ru    schedule 09.08.2018