我尝试使用@ 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)))
);
})
);
}
答案 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);
感谢您的帮助!