我有一个使用ngrx的Angular4应用程序。我创建了一个撤消的高阶缩减器,如文档on the redux website所示。
不幸的是,当我在root.reducers.ts文件中应用此函数时,我遇到了Ahead of Time(AoT)编译问题,并收到此错误
ERROR in Error encountered resolving symbol values statically. Calling function 'undoable', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol rootReducer
当关闭AoT或修改文件后,代码可以正常工作,在这种情况下,只使用时间编译。
我之前尝试过使用ngrx-undo,但它似乎没有用,这就是我推出自己解决方案的原因。
我已尝试查看其他stackoverflow帖子并搜索谷歌,但大多数其他问题似乎与第三方库或自定义组件有关,在这种情况下不相关。
我知道我可以通过删除高阶减速器并将cartReducer转换为可直接撤销来解决问题,但这是不可取的,因为如果我们让其他任何减速器都可以撤销,我们会有很多代码重复。
如何解决此错误?最好不要删除AoT编译,因为一旦我们投入生产就需要。
import { sessionReducer } from './reducers/session.reducers';
import { cartReducer } from './reducers/cart.reducer';
import { undoable } from './reducers/undo.reducer';
import { paymentReducer } from './reducers/payment.reducer';
import { accountReducer } from './reducers/account.reducer';
import { productReducer } from './reducers/product.reducer';
import { errorReducer } from './reducers/error.reducer';
export const rootReducer = {
session: sessionReducer,
cart: undoable(cartReducer),
payment: paymentReducer,
account: accountReducer,
product: productReducer,
error: errorReducer
};
答案 0 :(得分:1)
最后,我将大部分的undo reducer代码抽象为单独的函数,并返回一个构建特定reducer的函数。这似乎解决了这个问题
in cart.reducer.ts
const initialState: UndoState<CartState> = buildInitialState(initialCartState);
export function undoableCartReducer(state = initialState, action): UndoState<CartState> {
return handleAction(state, action, cartReducer);
}
在undo.reducer.ts
中export function buildInitialState<S>(state: S): UndoState<S> {
return {
past: [],
present: state,
future: []
};
}
export function delegate<S>(state: UndoState<S>, action, reducer: ActionReducer<S>): UndoState<S> {
const {past, present, future} = state;
const newPresent = reducer(present, action);
if (present === newPresent) {
return state;
}
return {
past: [...past, present],
present: newPresent,
future: []
};
}
export function handleAction<S>(state: UndoState<S>, action, reducer: ActionReducer<S>): UndoState<S> {
switch (action.type) {
case 'UNDO':
return undo(state);
case 'REDO':
return redo(state);
default:
return delegate(state, action, reducer);
}
}
new root.reducers.ts
export const rootReducer = {
session: sessionReducer,
cart: undoableCartReducer,
payment: paymentReducer,
account: accountReducer,
product: productReducer,
error: errorReducer
};