Angular 5 - return 另一个动态函数的函数
Angular 5 - Function that return another Dynamic Function
我创建了一个生成动态 switch-case 函数语句的函数。
export function generateReducer(initialState, reducerName: ReducerName, adapter: EntityAdapter<any>): (state, initialState) => IState {
reducerName.plural = reducerName.plural ? reducerName.plural : reducerName.singular + 's';
return function (state = initialState, action: any): IState {
switch (action.type) {
case `[${reducerName.plural} Section] Load Statistics ${reducerName.singular}`:
case `[${reducerName.plural} Section] Load Details ${reducerName.singular}`:
case `[${reducerName.plural} Section] Load ${reducerName.plural}`:
{
return { ...state, loading: true, loaded: false };
}
...
}
并像这样使用它
导出常量适配器:EntityAdapter = createEntityAdapter();
export const initialState: State = adapter.getInitialState({
loaded: false,
loading: false,
selectedId: null
});
export const reducer = generateReducer(initialState, { singular: 'Skill' }, adapter);
当 运行 使用 ng-serve
(不是 AOT)连接项目时一切正常,当尝试使用 ng build --prod
构建生产环境时,出现以下错误
ERROR in src\app\skills\skills.module.ts(46,45): Error during template
compile of 'SkillsModule' Function calls are not supported in
decorators but 'generateReducer' was called in 'reducers'
'reducers' references 'reducers'
'reducers' references 'reducer' at src\app\skills\store\reducers\index.ts(18,13)
'reducer' calls 'generateReducer' at src\app\skills\store\reducers\skills.reducer.ts(26,24).
试图找到任何方法来解决这个问题,但似乎我需要以某种方式将其提供给编译器,以便他可以告诉它一个生成代码的编译时函数。关于如何处理此类问题的任何想法?
编辑:
添加了一个 stackblitz 存储库来显示错误,
https://stackblitz.com/edit/reducer-factory-ngrx
下载应用程序,更新 package.json devDependencies "@angular/cli": "^1.6.0",
并尝试 运行 'ng build --prod'
尝试在 "reducer.ts" 添加:
export const reducer = generateReducer(initialState, { singular: 'Skill' }, adapter);
import { ActionReducerMap } from '@ngrx/store';
import { InjectionToken } from '@angular/core';
// register reducer token
export const reducerToken = new InjectionToken<ActionReducerMap<State>>(
'Registered Reducers'
);
Object.assign(reducerToken, reducer);
export function getReducers() {
return reducer;
}
并在 app.module.ts:
import { reducerToken, getReducers } from './reducer';
@NgModule({
imports: [
BrowserModule,
FormsModule,
StoreModule.forRoot(reducerToken)
],
declarations: [AppComponent, HelloComponent],
providers: [
{
provide: reducerToken,
useFactory: getReducers
}
],
bootstrap: [AppComponent]
})
这种方式对我有用...
希望对你有帮助
我创建了一个生成动态 switch-case 函数语句的函数。
export function generateReducer(initialState, reducerName: ReducerName, adapter: EntityAdapter<any>): (state, initialState) => IState {
reducerName.plural = reducerName.plural ? reducerName.plural : reducerName.singular + 's';
return function (state = initialState, action: any): IState {
switch (action.type) {
case `[${reducerName.plural} Section] Load Statistics ${reducerName.singular}`:
case `[${reducerName.plural} Section] Load Details ${reducerName.singular}`:
case `[${reducerName.plural} Section] Load ${reducerName.plural}`:
{
return { ...state, loading: true, loaded: false };
}
...
}
并像这样使用它
导出常量适配器:EntityAdapter = createEntityAdapter();
export const initialState: State = adapter.getInitialState({
loaded: false,
loading: false,
selectedId: null
});
export const reducer = generateReducer(initialState, { singular: 'Skill' }, adapter);
当 运行 使用 ng-serve
(不是 AOT)连接项目时一切正常,当尝试使用 ng build --prod
构建生产环境时,出现以下错误
ERROR in src\app\skills\skills.module.ts(46,45): Error during template compile of 'SkillsModule' Function calls are not supported in decorators but 'generateReducer' was called in 'reducers' 'reducers' references 'reducers' 'reducers' references 'reducer' at src\app\skills\store\reducers\index.ts(18,13) 'reducer' calls 'generateReducer' at src\app\skills\store\reducers\skills.reducer.ts(26,24).
试图找到任何方法来解决这个问题,但似乎我需要以某种方式将其提供给编译器,以便他可以告诉它一个生成代码的编译时函数。关于如何处理此类问题的任何想法?
编辑:
添加了一个 stackblitz 存储库来显示错误,
https://stackblitz.com/edit/reducer-factory-ngrx
下载应用程序,更新 package.json devDependencies "@angular/cli": "^1.6.0", 并尝试 运行 'ng build --prod'
尝试在 "reducer.ts" 添加:
export const reducer = generateReducer(initialState, { singular: 'Skill' }, adapter);
import { ActionReducerMap } from '@ngrx/store';
import { InjectionToken } from '@angular/core';
// register reducer token
export const reducerToken = new InjectionToken<ActionReducerMap<State>>(
'Registered Reducers'
);
Object.assign(reducerToken, reducer);
export function getReducers() {
return reducer;
}
并在 app.module.ts:
import { reducerToken, getReducers } from './reducer';
@NgModule({
imports: [
BrowserModule,
FormsModule,
StoreModule.forRoot(reducerToken)
],
declarations: [AppComponent, HelloComponent],
providers: [
{
provide: reducerToken,
useFactory: getReducers
}
],
bootstrap: [AppComponent]
})
这种方式对我有用... 希望对你有帮助