Skip to content

Commit 17571e5

Browse files
authored
feat(store): add object-style StoreModule.forFeature overload (#2821)
Closes #2809
1 parent 7f4e5ef commit 17571e5

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

modules/store/spec/modules.spec.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,34 @@ describe(`Store Modules`, () => {
216216
});
217217
});
218218
});
219+
220+
describe(`: With slice object`, () => {
221+
@NgModule({
222+
imports: [
223+
StoreModule.forFeature({ name: 'a', reducer: featureAReducer }),
224+
],
225+
})
226+
class FeatureAModule {}
227+
228+
@NgModule({
229+
imports: [StoreModule.forRoot({}), FeatureAModule],
230+
})
231+
class RootModule {}
232+
233+
beforeEach(() => {
234+
TestBed.configureTestingModule({
235+
imports: [RootModule],
236+
});
237+
238+
store = TestBed.inject(Store);
239+
});
240+
241+
it('should set up a feature state', () => {
242+
store.pipe(take(1)).subscribe((state: State) => {
243+
expect(state).toEqual({
244+
a: 5,
245+
} as State);
246+
});
247+
});
248+
});
219249
});

modules/store/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,6 @@ export {
5555
StoreFeatureModule,
5656
RootStoreConfig,
5757
StoreConfig,
58+
FeatureSlice,
5859
} from './store_module';
5960
export { On, on, createReducer } from './reducer_creator';

modules/store/src/store_module.ts

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ export interface RootStoreConfig<T, V extends Action = Action>
114114
runtimeChecks?: Partial<RuntimeChecks>;
115115
}
116116

117+
/**
118+
* An object with the name and the reducer for the feature.
119+
*/
120+
export interface FeatureSlice<T, V extends Action = Action> {
121+
name: string;
122+
reducer: ActionReducer<T, V>;
123+
}
124+
117125
@NgModule({})
118126
export class StoreModule {
119127
static forRoot<T, V extends Action = Action>(
@@ -192,15 +200,36 @@ export class StoreModule {
192200
reducer: ActionReducer<T, V> | InjectionToken<ActionReducer<T, V>>,
193201
config?: StoreConfig<T, V> | InjectionToken<StoreConfig<T, V>>
194202
): ModuleWithProviders<StoreFeatureModule>;
203+
static forFeature<T, V extends Action = Action>(
204+
slice: FeatureSlice<T, V>,
205+
config?: StoreConfig<T, V> | InjectionToken<StoreConfig<T, V>>
206+
): ModuleWithProviders<StoreFeatureModule>;
195207
static forFeature(
196-
featureName: string,
197-
reducers:
208+
featureNameOrSlice: string | FeatureSlice<any, any>,
209+
reducersOrConfig?:
198210
| ActionReducerMap<any, any>
199211
| InjectionToken<ActionReducerMap<any, any>>
200212
| ActionReducer<any, any>
201-
| InjectionToken<ActionReducer<any, any>>,
213+
| InjectionToken<ActionReducer<any, any>>
214+
| StoreConfig<any, any>
215+
| InjectionToken<StoreConfig<any, any>>,
202216
config: StoreConfig<any, any> | InjectionToken<StoreConfig<any, any>> = {}
203217
): ModuleWithProviders<StoreFeatureModule> {
218+
let featureName: string;
219+
let reducers:
220+
| ActionReducerMap<any, any>
221+
| InjectionToken<ActionReducerMap<any, any>>
222+
| ActionReducer<any, any>
223+
| InjectionToken<ActionReducer<any, any>>;
224+
if (typeof featureNameOrSlice === 'string') {
225+
featureName = featureNameOrSlice;
226+
reducers = reducersOrConfig as any;
227+
} else {
228+
featureName = featureNameOrSlice.name;
229+
reducers = featureNameOrSlice.reducer;
230+
config = (reducersOrConfig as any) ?? {};
231+
}
232+
204233
return {
205234
ngModule: StoreFeatureModule,
206235
providers: [

0 commit comments

Comments
 (0)