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

Phi*_*hil 12 ngrx angular

最近推出了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: [],
    };
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

mah*_*.cr 24

NgRx实体是一个处理大型数组的简单小型库,甚至认为文档没有解释如何在一个状态下使用多个实体,它应该很容易,因为它在幕后工作的库只是规范化数组并创建带有数据的字典.

为了使具有一个或多个实体的状态工作,请遵循以下步骤:

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

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

interface PlaceState extends EntityState<Place> {
  total: number;
}
Run Code Online (Sandbox Code Playgroud)

然后创建一个包含实体的状态

export interface State {
  msg: string;
  cars: CarState;
  places: PlaceState;
}
Run Code Online (Sandbox Code Playgroud)

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

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

const carInitialState: CarState = adapterCar.getInitialState({ total: 0 });
const placeInitialState: PlaceState = adapterPlace.getInitialState({ total: 0 });
Run Code Online (Sandbox Code Playgroud)

定义初始全局状态

const initialState = {
  msg: 'Multiple entities in the same state',
  cars: carInitialState,
  places: placeInitialState
}
Run Code Online (Sandbox Code Playgroud)

创建减速器:

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

}
Run Code Online (Sandbox Code Playgroud)

暴露选择器

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();
Run Code Online (Sandbox Code Playgroud)

而已 :)

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

  • 而不是这样: `export const { selectAll: selectAllCars } = adapterCar.getSelectors();` 这对我有用: `export const { selectAll: selectAllCars } = adapterCar.getSelectors(selectCarState);` (3认同)
  • 非常感谢您提供这个示例,几周来我一直在思考如何做到这一点,而 ngrx 文档对于现实世界的使用来说远非“简单” (3认同)