Angular NGRX:一个EntityAdapter中的多个实体可能吗?

时间:2018-02-05 11:11:36

标签: angular ngrx

最近推出了NGRX / Entities:

https://medium.com/ngrx/introducing-ngrx-entity-598176456e15 https://github.com/ngrx/platform/tree/master/example-app

因为它们是以适配器处理(读取:单个)映射数据结构的方式制作的,并且在初始化时获得剩余的reducer状态,我想知道......

是否可以在一个减速器/适配器中容纳多个实体?接口说没有,但可能有黑客或计划未来?如果我在一个reducer中已经有多个地图怎么办?我是否被迫将其拆分或避开实体功能?

以下答案有效。另一种方法(在这个例子中是懒惰加载但不一定是)模块是将reducers与ActionReducerMap结合使用:

你的lazy.module.ts中的

export interface LazyState {
  lazyAState: LazyAState;
  lazyBState: LazyBState;
}

export const lazyReducers: ActionReducerMap<LazyState> = {
  lazyA: lazyAReducer,
  lazyB: lazyBReducer
};

export interface AppState extends forRoot.AppState {
  lazy: LazyState;
}

@NgModule({
  imports: [
    LazyRoutingModule,
    StoreModule.forFeature('lazy', lazyReducers),
    EffectsModule.forFeature([LazyEffects])
  ]
})
export class LazyModule {
  static forRoot() {
    return {
      ngModule: LazyModule,
      providers: [],
    };
  }
}

在lazy.selectors.ts中(从reducer-file导入适配器):

export const getLazyState = createFeatureSelector<LazyState>('lazy');

const getLazyAState = createSelector(getLazyState, (state: LazyState) => state.lazyAState);
const getLazyBState = createSelector(getLazyState, (state: LazyState) => state.lazyBState);

const {selectEntities: lazyASelectEntities, selectAll: lazyASelectAll} = LAZY_A_ADAPTER.getSelectors();

export const lazyADictionary = createSelector(getLazyAState, lazyASelectEntities);
export const lazyAArray = createSelector(getLazyAState, lazyASelectAll);
export const lazyASomeOtherAttributeNotFromAdapter = createSelector(getLazyAState, (state: LazyAState) => state.ids as string[]);

const {selectEntities: lazyBSelectEntities, selectAll: lazyBSelectAll} = LAZY_B_ADAPTER.getSelectors();
// same as for lazy-A, you can also combine selectors if you want

1 个答案:

答案 0 :(得分:13)

NgRx实体是一个处理大型数组的简单小型库,即使文档未解释如何在一种状态下使用多个实体,也应该很容易,因为该库在幕后所做的只是规范化了数组并使用数据创建字典。

为了使一个或多个实体处于工作状态,请执行以下步骤:

首先定义每个实体的状态。

interface CarState extends EntityState<Car> {
  total: number;
}

interface PlaceState extends EntityState<Place> {
  total: number;
}

然后创建一个保存实体的状态

export interface State {
  msg: string;
  cars: CarState;
  places: PlaceState;
}

为每个实体状态创建适配器以操纵数据并创建初始状态。

const adapterCar = createEntityAdapter<Car>();
const adapterPlace = createEntityAdapter<Place>();

const carInitialState: CarState = adapterCar.getInitialState({ total: 0 });
const placeInitialState: PlaceState = adapterPlace.getInitialState({ total: 0 });

定义初始全局状态

const initialState = {
  msg: 'Multiple entities in the same state',
  cars: carInitialState,
  places: placeInitialState
}

创建减速器:

export function reducer(state: State = initialState, action: ExampleActions): State {

  switch (action.type) {

    case ExampleActionTypes.GetCarList:
      return { ...state, cars: adapterCar.addMany(action.payload, state.cars) };

    case ExampleActionTypes.GetPlaceList:
      return { ...state, places: adapterPlace.addMany(action.payload, state.places) };

    default:
      return state;
  }

}

暴露选择器

export const selectCarState = (state: State) => state.cars;
export const selectPlaceState = (state: State) => state.places;

export const { selectAll: selectAllCars } = adapterCar.getSelectors();
export const { selectAll: selectAllPlaces } = adapterPlace.getSelectors();

就这样:)

实时示例: https://stackblitz.com/edit/angular-ngrx-store