我目前正在开发一个简单的测试应用程序,以了解有关@ ngrx / store的更多信息。我有一个名为TrainingModule的模块,它应该存储一些练习和更多信息。 代码有效,但我试着在这里改进。我目前拥有的是我的功能模块,如下所示:
@NgModule({
imports: [
CommonModule,
TrainingRoutingModule,
StoreModule.forFeature('exercises', exerciseReducer)
],
declarations: [
TrainingDashboardComponent,
TrainingCoreComponent,
TrainingNavComponent,
TrainingPlanComponent,
ExerciseOverviewComponent,
ExerciseListComponent]
})
export class TrainingModule {
}
和我的减速机看起来像那样:
export interface ExerciseState {
exercises: IExercise[];
}
export interface State extends fromRoot.State {
'exercises': ExerciseState;
}
export const initialState: ExerciseState = {
exercises: [
{id: 1, name: 'Exc 1'},
{id: 2, name: 'Exc 2'}
]
};
export function exerciseReducer(state: ExerciseState = initialState, action: any): ExerciseState {
switch (action.type) {
default:
return state;
}
}
export const getExerciseState = createFeatureSelector<ExerciseState>('exercises');
export const getExercises = createSelector(getExerciseState, state => state.exercises);
到目前为止一切顺利。在我的模板中,我使用
从商店中选择我的练习exercise$: Observable<IExercise[]>;
constructor(private store: Store<State>) { }
ngOnInit() {
this.exercise$ = this.store.select(getExercises);
}
所以我现在要做的就是将我的减速器组合在一起,这样我就不必像这样添加每个减速器了
StoreModule.forFeature('exercises', exerciseReducer);
StoreModule.forFeature('sample', sampleReducer);
StoreModule.forFeature('sample1', sampleReducer1);
在我的所有模块中。 我试图用
收集所有减速器export const trainingReducers = {
'exercise': exerciseReducer
};
和
StoreModule.forFeature('training', trainingReducers)
但是这给了我一个无法在控制台中读取未定义错误消息的属性'练习'。也许有人可以帮助我理解,我如何从特征模块中收集所有减少器并为其创建一个正确的选择器。
答案 0 :(得分:13)
我可以举个例子来说明我是怎么做到的。我使用index.ts来捆绑模块中的所有其他reducer,如下所示:
模块/减速器/ index.ts
import * as fromRoot from '../../../reducers';
import * as fromSearch from './search';
import * as fromUserDetail from './user-detail';
import * as fromDetailBase from './base';
export interface UserModuleState {
search: fromSearch.State;
detail: fromUserDetail.State;
detailBase: fromDetailBase.State;
}
export interface State extends fromRoot.State {
userModule: UserModuleState;
}
export const reducers = {
search: fromSearch.reducer,
detail: fromUserDetail.reducer,
detailBase : fromDetailBase.reducer
};
export const selectUserModuleState = createFeatureSelector<UserModuleState>('userModule');
export const selectSearchState = createSelector(
selectUserModuleState, (state: UserModuleState) => state.search
);
export const getSearchLoading = createSelector(selectSearchState, fromSearch.getLoading);
export const getSearchEntities = createSelector(selectSearchState, fromSearch.getEntities);
模块/ user.module.ts
import { reducers } from './reducers';
@NgModule({
imports: [
...
StoreModule.forFeature('userModule', reducers)
],
...
})
export default class UserModule { }
答案 1 :(得分:1)
您的设置几乎正确。
在createFeatureSelector
函数中,您在商店的根目录中声明了功能键,在示例中为'exercises'。因此,例如,您将选择store.exercises.exercises.id
,而功能选择器只是store.exercises
的快捷方式。
但是,在StoreModule.forFeature('training', trainingReducers)
调用中,您将“培训”定义为功能模块的根密钥。
正确的设置如下所示:
export const featureReducersMap = {
exercise: exerciseReducer,
anyOtherKey: anyOtherReducer
};
StoreModule.forFeature('myFeatureModule', featureReducersMap);
export interface FeatureState{
exercise: string;
anyOtherKey: number;
}
然后编写如下选择器:
export const featureSelector = createFeatureSelector<FeatureState>('myFeatureModule');
export const exerciseSelector = createSelector(
featureSelector,
(state: FeatureState) => state.exercise
);
建议将功能键存储在变量中,而不是对其进行硬编码。