在静态解析符号时遇到错误

时间:2017-07-27 17:57:46

标签: angular typescript redux ngrx

我有一个使用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编译,因为一旦我们投入生产就需要。

代码:

See Gist for complete code

root.reducers.ts

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
};

1 个答案:

答案 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
};