使用@ ngrx / entity处理商店中的集合,getSelectors()无效

时间:2018-04-22 13:08:07

标签: angular typescript redux ngrx

我尝试使用@ ngrx / entity lib实现NgRx商店,但我无法使用@ ngrx / entity getSelectors检索任何数据。 Redux Devtools将Effect()的加载显示为实体。所以我的效果正常。现在,我想使用selectAll函数中的adapter.getSelectors()选择器将数据选择为数组。我的减速器索引如下所示

减速器/ index.ts

import { ActionReducerMap, createFeatureSelector, createSelector } from '@ngrx/store';

import * as fromModels from './models.reducer';
import { EntityState } from '@ngrx/entity';

export interface State {
  models: fromModels.State;
}

export const reducers: ActionReducerMap<State> = {
  models: fromModels.reducer
};

export const getModelsState = createFeatureSelector<fromModels.State>('models');
export const { selectAll: getAllModels } = fromModels.adapter.getSelectors(getModelsState);

减速器/ models.reducer.ts

import { createFeatureSelector, createSelector } from '@ngrx/store';
import { createEntityAdapter, EntityState, EntityAdapter } from '@ngrx/entity';

import { ModelsActions, ModelsActionTypes } from '../actions';
import { Model } from '../../models/model';

export const adapter: EntityAdapter<Model> = createEntityAdapter<Model>({
  selectId: model => model.id,
  sortComparer: (modelA, modelB) => modelA.id === modelB.id ? 0 : (modelA.id === modelB.id ? 1 : -1)
});

export interface State extends EntityState<Model> {}
const initialState = adapter.getInitialState();

export function reducer(state = initialState, action: ModelsActions): State {
  switch (action.type) {

    case ModelsActionTypes.LoadSuccess:
      return adapter.addAll(action.payload, state);

    default: return state;
  }
}

在我的容器组件中,我想通过ngrx / entity选择器选择数据,并使用异步管道显示数据。 (我减少了模板)

models.component.ts

// All other import statements
import { Store, select } from '@ngrx/store';
import * as fromFeature from '../store';

@Component({
  template: `{{models$ | async}} | json`
})
export class ModelsComponent implements OnInit {
  models$: Observable<Model[]>;

  constructor(private store: Store<fromFeature.State>) {}

  ngOnInit() {
    this.models$ = this.store.select(fromFeature.getAllModels);
    this.store.dispatch(new fromFeature.LoadModels());
  }
}

控制台输出错误

ModelsComponent.html:2
ERROR TypeError: Cannot read property 'ids' of undefined
at selectIds (entity.es5.js:45)
at eval (store.es5.js:572)

任何解决此问题的建议或想法?谢谢!

更新[请求的模板]

模板只订阅models$ observable,与reduce模板中的相同。 model-card.component.ts 只会获取输入()&<39>和 ng-content

<app-model-card
  *ngFor="let model of models$ | async"
  [logo]="model.id"
  [routerLink]="[model.id]">
  {{model.title}}
</app-model-card>

更新[请求的操作]

操作/ models.action.ts

import { Action } from '@ngrx/store';
import { Model } from '../../models/model';

export enum ModelsActionTypes {
  Load = '[Models] Load',
  LoadSuccess = '[Models] Load Success',
  LoadFailed = '[Models] Load Failed'
}

export class LoadModels implements Action {
  readonly type = ModelsActionTypes.Load;
}

export class LoadModelsSuccess implements Action {
  readonly type = ModelsActionTypes.LoadSuccess;

  constructor(public payload: Model[]) {}
}

export class LoadModelsFailed implements Action {
  readonly type = ModelsActionTypes.LoadFailed;

  constructor(public payload: any) {}
}

export type ModelsActions =
  LoadModels |
  LoadModelsSuccess |
  LoadModelsFailed;

models.effects.ts

import { Injectable } from '@angular/core';
import { Actions, Effect } from '@ngrx/effects';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { map, switchMap, catchError } from 'rxjs/operators';

import { ModelsActionTypes, LoadModelsSuccess, LoadModelsFailed } from 
  '../actions';
import { ModelsService } from '../../services/models.service';

@Injectable()
export class ModelsEffects {
  constructor(
    private actions$: Actions,
    private modelsService: ModelsService
  ) {}

  @Effect()
  loadModels$ = this.actions$
    .ofType(ModelsActionTypes.Load)
    .pipe(
      switchMap(() => {
        return this.modelsService.getModels().pipe(
          map(models => new LoadModelsSuccess(models)),
          catchError(error => of(new LoadModelsFailed(error)))
        );
      })
    );
}

1 个答案:

答案 0 :(得分:3)

哦,该死,我明白了。问题是createFeatureSelector,它只选择功能(顾名思义)。我将模块注册为StoreModule.forFeature('configuration', reducers)

然后解决方案是从Feature选择器获取ConfigurationState,模型从默认选择器状态。

<强>减速器/ index.ts

[...]
export const getConfigurationState = createFeatureSelector<ConfigurationState>('configuration');
export const getModelsState = createSelector(
  getConfigurationState,
  (configuration) => configuration.models
);

export const {
  selectIds,
  selectEntities,
  selectAll
} = fromModels.adapter.getSelectors(getModelsState);

感谢您的帮助!

相关问题