Angular 角度NGRX:一个实体中可能有多个实体适配器?

Angular 角度NGRX:一个实体中可能有多个实体适配器?,angular,ngrx,Angular,Ngrx,最近引入了NGRX/实体: 由于它们是以一种适配器处理(读取:一个,单个)映射数据结构的方式生成的,并且在初始化时会获得其余的reducer状态,所以我想知道 是否可以在一个减速器/适配器中容纳多个实体?界面上说没有,但可能有黑客攻击,或者是计划在未来?如果我在一个减速器中已经有多个贴图怎么办?我是被迫将其拆分还是避免使用实体功能 下面的答案是有效的。模块(在本例中是延迟加载的,但不一定)的另一种方法是将Reducer与ActionReducerMap结合起来: 在lazy.module.t

最近引入了NGRX/实体:

由于它们是以一种适配器处理(读取:一个,单个)映射数据结构的方式生成的,并且在初始化时会获得其余的reducer状态,所以我想知道

是否可以在一个减速器/适配器中容纳多个实体?界面上说没有,但可能有黑客攻击,或者是计划在未来?如果我在一个减速器中已经有多个贴图怎么办?我是被迫将其拆分还是避免使用实体功能

下面的答案是有效的。模块(在本例中是延迟加载的,但不一定)的另一种方法是将Reducer与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: [],
    };
  }
}
导出接口懒散状态{
懒司他酯:懒司他酯;
懒散状态:懒散状态;
}
导出常量LazyReducer:ActionReducerMap={
懒洋洋:懒洋洋,
懒汉
};
导出接口AppState扩展了forRoot.AppState{
懒惰:懒散状态;
}
@NGD模块({
进口:[
懒散模块,
StoreModule.forFeature('lazy',lazyReducers),
EffectsModule.forFeature([LazyEffects])
]
})
导出类LazyModule{
静态forRoot(){
返回{
NGM模块:LazyModule,
提供者:[],
};
}
}
在lazy.selectors.ts中(从reducer文件导入适配器):

导出常量getLazyState=createFeatureSelector('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); 导出const lazyASomeOtherAttributeNotFromAdapter=createSelector(getLazyAState,(state:LazyAState)=>state.ids作为字符串[]); const{selectEntities:lazyBSelectEntities,selectAll:lazyBSelectAll}=LAZY_B_ADAPTER.getSelectors(); //与lazy-A相同,如果需要,也可以组合选择器
NgRx entity是一个简单的小型库,用于处理大型阵列,即使文档中没有说明如何在一种状态下使用多个实体,它也应该很容易,因为该库在幕后所做的只是规范化阵列并用数据创建字典

要使状态与一个或多个实体协同工作,请执行以下步骤:

首先定义每个实体的状态

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

interface PlaceState extends EntityState<Place> {
  total: number;
}
为每个实体状态创建适配器,以操作数据并创建初始状态

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

const carInitialState: CarState = adapterCar.getInitialState({ total: 0 });
const placeInitialState: PlaceState = adapterPlace.getInitialState({ total: 0 });
创建减速器:

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();
就这样:)


现场示例:

是的,我们当时也是这么做的。事实证明,拆分reducer/state对于体系结构来说也是一个好主意,因为当您需要管理多个映射(而不是一些布尔标志)时,您可能应该使用专用的子reducer来保持清楚。@Phil您是如何拆分reducer的?在默认情况下传递函数?我在两个单独的文件中有两个还原器/状态。我将编辑我的问题以显示如何组合它们,而不是这样:
export const{selectAll:selectAllCars}=adapterCar.getSelectors()这对我很有效:
导出常量{selectAll:selectAllCars}=adapterCar.getSelectors(selectCarState)非常感谢您提供了这个示例,几周来我一直在努力思考如何做到这一点,而ngrx文档对于现实世界的使用来说非常“简单”
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();