web-dev-qa-db-ja.com

Angular NGRX:1つのEntityAdapterで複数のエンティティが可能ですか?

最近NGRX /エンティティが導入されました:

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

そして、それらはアダプターが(read:one、single)マップデータ構造を処理し、初期化時に残りのレデューサー状態を取得する方法で作成されているので、私は不思議に思っていました...

1つのレデューサー/アダプターに複数のエンティティを保持することは可能ですか?インターフェースに「いいえ」と表示されていますが、ハックがあるか、将来的に計画されていますか? 1つのレデューサーに複数のマップが既にある場合はどうなりますか?分割するか、エンティティ機能を使わざるを得ませんか?

以下の答えは有効です。 (この例では遅延ロードされますが、必ずしもそうではありません)モジュールの別のアプローチは、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: [],
    };
  }
}

そして、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
12
Phil

NgRxエンティティは、ドキュメントが1つの状態で複数のエンティティを使用する方法を説明していない場合でも、大きな配列を処理するシンプルで小さなライブラリです。バックグラウンドで実行するライブラリは、配列を正規化して作成するだけなので、簡単です。データを含む辞書。

1つ以上のエンティティで状態を機能させるには、次の手順に従います。

まず、各エンティティの状態を定義します。

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-multiple-entities-in-same-state

22
mah.cr