简体   繁体   English

如何为Angular ngrx商店制作一个“reducer enhancer”来进行撤销/重做

[英]How to make a “reducer enhancer” for Angular ngrx store for undo / redo

I would like to add a reducer enhancer or meta reducer for a specific store slice. 我想为特定的商店切片添加reducer Enhancer或meta reducer。 I've implemented a function that takes in a reducer and enables undo / redo functionality. 我已经实现了一个接收reducer并启用撤消/重做功能的函数。 It currently looks like this: 它目前看起来像这样:

export const adminReducers: ActionReducerMap<AdminFeatureState> = {
    admin: admin.reducer,
    dynamicForm: undoable(dynamicForm.reducer, DynamicFormActionTypes.UNDO, DynamicFormActionTypes.REDO, [
        DynamicFormActionTypes.SELECTED_DYNAMIC_CONTROLS_CHANGED,
        DynamicFormActionTypes.CHANGE_GROUP,
        DynamicFormActionTypes.RESET,
        DynamicFormActionTypes.ADD_PAGE,
        DynamicFormActionTypes.REMOVE_PAGE,
        DynamicFormActionTypes.REORDER_GROUPS,
        DynamicFormActionTypes.SAVE_EDIT_CONTROL
    ])
};

export function undoable<T>(reducer: ActionReducer<any>, undoActionType: string, redoActionType: string, recordedActions: string[]): ActionReducer<any> {
    // Call the reducer with empty action to populate the initial state
    const initialState: UndoableState<T> = {
        past: [],
        present: reducer(undefined, { type: 'INIT' }),
        future: []
    };

    // Return a reducer that handles undo and redo
    return function (state = initialState, action) {
    ...
    };
}

Everything works great except when I build for production I get the following error: 一切都很好,除非我为生产而构建时出现以下错误:

Error during template compile of 'AdminModule'
  Function calls are not supported in decorators but 'undoable' was called in 'adminReducers'
    'adminReducers' calls 'undoable' at src\app\core\containers\admin\admin-feature.reducers.ts(11,29).

The only other way I have seen you can enhance an existing reducer is using meta-reducers but those get called for every reducer function, not just a specific one such as the 'dynamicForm' in this case. 我看到你可以增强现有reducer的唯一另一种方法是使用meta-reducers,但是每个reducer函数调用它们,而不仅仅是特定的一个,例如本例中的'dynamicForm'。

After some digging in the docs I found the solution here: 在对文档进行了一些挖掘之后,我在这里找到了解决方案:

https://github.com/ngrx/platform/blob/master/docs/store/api.md#feature-module-reducers-and-aot https://github.com/ngrx/platform/blob/master/docs/store/api.md#feature-module-reducers-and-aot

You can simply wrap 'adminReducers' in combineReducers like so: 你可以简单地在combineReducers中包装'adminReducers',如下所示:

const adminReducers: ActionReducerMap<AdminFeatureState> = {
    admin: admin.reducer,
    dynamicForm: undoable(dynamicForm.reducer, DynamicFormActionTypes.UNDO, DynamicFormActionTypes.REDO, [
        DynamicFormActionTypes.SELECTED_DYNAMIC_CONTROLS_CHANGED,
        DynamicFormActionTypes.CHANGE_GROUP,
        DynamicFormActionTypes.RESET,
        DynamicFormActionTypes.ADD_PAGE,
        DynamicFormActionTypes.REMOVE_PAGE,
        DynamicFormActionTypes.REORDER_GROUPS,
        DynamicFormActionTypes.SAVE_EDIT_CONTROL
    ])
};

const adminMetaReducer = combineReducers(adminReducers);

export function enhancedAdminReducers(state, action) {
    return adminMetaReducer(state, action);
}

Then import that into your module 然后将其导入您的模块

StoreModule.forFeature(ADMIN_FEATURE, enhancedAdminReducers),

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM