Javascript 如何在Polymer3 Redux中从mixin调用MapStateTops方法

Javascript 如何在Polymer3 Redux中从mixin调用MapStateTops方法,javascript,redux,polymer-3.x,Javascript,Redux,Polymer 3.x,我在示例中使用了github的聚合物redux repo: 我有redux todo组件,它将todoApp与redux存储连接起来。我还创建了一个mixin,我想从中继承一些属性,同时我想从mixin将这个属性中的一个连接到存储。我设法从mixin调用mapStateToProps方法,但不幸的是,它从未将属性绑定到存储 以下是我到目前为止的情况: redux todo.js: import TodoApp from 'todo-app'; import ReduxMixin from 'm

我在示例中使用了github的聚合物redux repo:

我有redux todo组件,它将todoApp与redux存储连接起来。我还创建了一个mixin,我想从中继承一些属性,同时我想从mixin将这个属性中的一个连接到存储。我设法从mixin调用mapStateToProps方法,但不幸的是,它从未将属性绑定到存储

以下是我到目前为止的情况:

redux todo.js:

import TodoApp from 'todo-app';
import ReduxMixin from 'mixins/redux';
import { bindActionCreators } from 'polymer-redux';
import { AnotherMixin } from 'another-mixin.js';
import { ExtraMixin } from 'extra-mixin.js';

class ReduxTodo extends AnotherMixin(ExtraMixin(ReduxMixin(TodoApp))) {
    /**
     * We map any redux state to the element properties here. Feel free to use
     * libraries like reselect to improve the performance of your app.
     *
     * @param {object} state The redux state object.
     * @param {HTMLElement} element The element instance.
     *
     * @return {Object} Key-value map of properties and their values.
     */


    static mapStateToProps(state, element) {
        super.mapStateToProps(state);
        console.log('mapping props');
        console.dir(state);
        console.dir(this);
        return {
            tasks: state.tasks,
            extras: state.extras,//from extras mixin
            //another: state.another
        };
    }

    constructor(){
        super();
        console.log(this.extras);
        console.log(this.another);
    }

    ready() {
        super.ready();
        // do something that requires access to the shadow tree
        console.log(this.extras);
        console.log(this.another);
        console.log(this.tasks);
        //console.log(this.mapStateToProps);
        ;
      }


    /**
     * Mapping dispatch to CustomEvents that bubble from internal elements.
     * This is only called once so make sure you bind correctly.
     *
     * Use the exported helper `bindActionCreators` to construct a key-value map
     * of events that will call `dispatch` with the returning value.
     *
     * @param {Function} dispatch The redux dispatch function.
     * @param {HTMLElement} element The element instance.
     *
     * @return {Object} Key-value map of event names and their listeners.
     */
    static mapDispatchToEvents(dispatch, element) {
        return bindActionCreators(
            {
                addTask(event) {
                    return {
                        type: 'ADD_TASK',
                        task: event.detail
                    };
                },
                updateTaskDone(event) {
                    return {
                        type: 'UPDATE_TASK_DONE',
                        index: event.detail.index,
                        done: event.detail.done
                    };
                },
                removeTask(event) {
                    return {
                        type: 'REMOVE_TASK',
                        index: event.detail
                    };
                }
            },
            dispatch
        );
    }
}

customElements.define('redux-todo', ReduxTodo);
import {dedupingMixin} from '@polymer/polymer/lib/utils/mixin.js';
import ReduxMixin from 'mixins/redux';

let internalAnotherMixin = (base) =>
  class extends ReduxMixin(base) {
    static get properties() {
        return {
            another:{
                type:Boolean,
                value: true
            } 
        };
    }
    constructor(){
        super();
        console.log("Hello from another constructor");
        //this.another = true;
    }

    static mapStateToProps(state, element) {
        console.log('mapping props from another-mixin');
        console.dir(this);
        console.dir(state);
        return {
            another: state.another
        };
    }

  }

  export const AnotherMixin = dedupingMixin(internalAnotherMixin);
import {dedupingMixin} from '@polymer/polymer/lib/utils/mixin.js';

let internalExtraMixin = (base) =>
  class extends base {
    static get properties() {
        return {
            extras: String
        };
    }
    constructor(){
        super();
        console.log("Hello from extras constructor");
        //this.extras = "Hello world";
    }
  }

  export const ExtraMixin = dedupingMixin(internalExtraMixin);
...
class ReduxTodo extends AnotherMixin(ExtraMixin((TodoApp))) {
...
}
另一个mixin.js:

import TodoApp from 'todo-app';
import ReduxMixin from 'mixins/redux';
import { bindActionCreators } from 'polymer-redux';
import { AnotherMixin } from 'another-mixin.js';
import { ExtraMixin } from 'extra-mixin.js';

class ReduxTodo extends AnotherMixin(ExtraMixin(ReduxMixin(TodoApp))) {
    /**
     * We map any redux state to the element properties here. Feel free to use
     * libraries like reselect to improve the performance of your app.
     *
     * @param {object} state The redux state object.
     * @param {HTMLElement} element The element instance.
     *
     * @return {Object} Key-value map of properties and their values.
     */


    static mapStateToProps(state, element) {
        super.mapStateToProps(state);
        console.log('mapping props');
        console.dir(state);
        console.dir(this);
        return {
            tasks: state.tasks,
            extras: state.extras,//from extras mixin
            //another: state.another
        };
    }

    constructor(){
        super();
        console.log(this.extras);
        console.log(this.another);
    }

    ready() {
        super.ready();
        // do something that requires access to the shadow tree
        console.log(this.extras);
        console.log(this.another);
        console.log(this.tasks);
        //console.log(this.mapStateToProps);
        ;
      }


    /**
     * Mapping dispatch to CustomEvents that bubble from internal elements.
     * This is only called once so make sure you bind correctly.
     *
     * Use the exported helper `bindActionCreators` to construct a key-value map
     * of events that will call `dispatch` with the returning value.
     *
     * @param {Function} dispatch The redux dispatch function.
     * @param {HTMLElement} element The element instance.
     *
     * @return {Object} Key-value map of event names and their listeners.
     */
    static mapDispatchToEvents(dispatch, element) {
        return bindActionCreators(
            {
                addTask(event) {
                    return {
                        type: 'ADD_TASK',
                        task: event.detail
                    };
                },
                updateTaskDone(event) {
                    return {
                        type: 'UPDATE_TASK_DONE',
                        index: event.detail.index,
                        done: event.detail.done
                    };
                },
                removeTask(event) {
                    return {
                        type: 'REMOVE_TASK',
                        index: event.detail
                    };
                }
            },
            dispatch
        );
    }
}

customElements.define('redux-todo', ReduxTodo);
import {dedupingMixin} from '@polymer/polymer/lib/utils/mixin.js';
import ReduxMixin from 'mixins/redux';

let internalAnotherMixin = (base) =>
  class extends ReduxMixin(base) {
    static get properties() {
        return {
            another:{
                type:Boolean,
                value: true
            } 
        };
    }
    constructor(){
        super();
        console.log("Hello from another constructor");
        //this.another = true;
    }

    static mapStateToProps(state, element) {
        console.log('mapping props from another-mixin');
        console.dir(this);
        console.dir(state);
        return {
            another: state.another
        };
    }

  }

  export const AnotherMixin = dedupingMixin(internalAnotherMixin);
import {dedupingMixin} from '@polymer/polymer/lib/utils/mixin.js';

let internalExtraMixin = (base) =>
  class extends base {
    static get properties() {
        return {
            extras: String
        };
    }
    constructor(){
        super();
        console.log("Hello from extras constructor");
        //this.extras = "Hello world";
    }
  }

  export const ExtraMixin = dedupingMixin(internalExtraMixin);
...
class ReduxTodo extends AnotherMixin(ExtraMixin((TodoApp))) {
...
}
extra mixin.js:

import TodoApp from 'todo-app';
import ReduxMixin from 'mixins/redux';
import { bindActionCreators } from 'polymer-redux';
import { AnotherMixin } from 'another-mixin.js';
import { ExtraMixin } from 'extra-mixin.js';

class ReduxTodo extends AnotherMixin(ExtraMixin(ReduxMixin(TodoApp))) {
    /**
     * We map any redux state to the element properties here. Feel free to use
     * libraries like reselect to improve the performance of your app.
     *
     * @param {object} state The redux state object.
     * @param {HTMLElement} element The element instance.
     *
     * @return {Object} Key-value map of properties and their values.
     */


    static mapStateToProps(state, element) {
        super.mapStateToProps(state);
        console.log('mapping props');
        console.dir(state);
        console.dir(this);
        return {
            tasks: state.tasks,
            extras: state.extras,//from extras mixin
            //another: state.another
        };
    }

    constructor(){
        super();
        console.log(this.extras);
        console.log(this.another);
    }

    ready() {
        super.ready();
        // do something that requires access to the shadow tree
        console.log(this.extras);
        console.log(this.another);
        console.log(this.tasks);
        //console.log(this.mapStateToProps);
        ;
      }


    /**
     * Mapping dispatch to CustomEvents that bubble from internal elements.
     * This is only called once so make sure you bind correctly.
     *
     * Use the exported helper `bindActionCreators` to construct a key-value map
     * of events that will call `dispatch` with the returning value.
     *
     * @param {Function} dispatch The redux dispatch function.
     * @param {HTMLElement} element The element instance.
     *
     * @return {Object} Key-value map of event names and their listeners.
     */
    static mapDispatchToEvents(dispatch, element) {
        return bindActionCreators(
            {
                addTask(event) {
                    return {
                        type: 'ADD_TASK',
                        task: event.detail
                    };
                },
                updateTaskDone(event) {
                    return {
                        type: 'UPDATE_TASK_DONE',
                        index: event.detail.index,
                        done: event.detail.done
                    };
                },
                removeTask(event) {
                    return {
                        type: 'REMOVE_TASK',
                        index: event.detail
                    };
                }
            },
            dispatch
        );
    }
}

customElements.define('redux-todo', ReduxTodo);
import {dedupingMixin} from '@polymer/polymer/lib/utils/mixin.js';
import ReduxMixin from 'mixins/redux';

let internalAnotherMixin = (base) =>
  class extends ReduxMixin(base) {
    static get properties() {
        return {
            another:{
                type:Boolean,
                value: true
            } 
        };
    }
    constructor(){
        super();
        console.log("Hello from another constructor");
        //this.another = true;
    }

    static mapStateToProps(state, element) {
        console.log('mapping props from another-mixin');
        console.dir(this);
        console.dir(state);
        return {
            another: state.another
        };
    }

  }

  export const AnotherMixin = dedupingMixin(internalAnotherMixin);
import {dedupingMixin} from '@polymer/polymer/lib/utils/mixin.js';

let internalExtraMixin = (base) =>
  class extends base {
    static get properties() {
        return {
            extras: String
        };
    }
    constructor(){
        super();
        console.log("Hello from extras constructor");
        //this.extras = "Hello world";
    }
  }

  export const ExtraMixin = dedupingMixin(internalExtraMixin);
...
class ReduxTodo extends AnotherMixin(ExtraMixin((TodoApp))) {
...
}
如果我从redux-todo.js调用mapStateToProps方法,它会正常工作,但是如果我想在不同的类中使用mixin,我必须在所有类中使用它,所以我只是想知道是否可以从mixin调用它

在存储中,另一个属性的值为false。在运行我的代码并记录道具之后,它仍然是真的,所以它不起作用

编辑1: 我还注意到每个动作都会被调用两次。因此,当我向todo列表中添加某些内容时,元素会被添加到列表中2次 我通过从redux-todo.js中删除ReduxMixin修复了这个问题。因为我将它添加到另一个-mixin.js中,所以redux-todo.js将继承它

这是新的redux.todo.js:

import TodoApp from 'todo-app';
import ReduxMixin from 'mixins/redux';
import { bindActionCreators } from 'polymer-redux';
import { AnotherMixin } from 'another-mixin.js';
import { ExtraMixin } from 'extra-mixin.js';

class ReduxTodo extends AnotherMixin(ExtraMixin(ReduxMixin(TodoApp))) {
    /**
     * We map any redux state to the element properties here. Feel free to use
     * libraries like reselect to improve the performance of your app.
     *
     * @param {object} state The redux state object.
     * @param {HTMLElement} element The element instance.
     *
     * @return {Object} Key-value map of properties and their values.
     */


    static mapStateToProps(state, element) {
        super.mapStateToProps(state);
        console.log('mapping props');
        console.dir(state);
        console.dir(this);
        return {
            tasks: state.tasks,
            extras: state.extras,//from extras mixin
            //another: state.another
        };
    }

    constructor(){
        super();
        console.log(this.extras);
        console.log(this.another);
    }

    ready() {
        super.ready();
        // do something that requires access to the shadow tree
        console.log(this.extras);
        console.log(this.another);
        console.log(this.tasks);
        //console.log(this.mapStateToProps);
        ;
      }


    /**
     * Mapping dispatch to CustomEvents that bubble from internal elements.
     * This is only called once so make sure you bind correctly.
     *
     * Use the exported helper `bindActionCreators` to construct a key-value map
     * of events that will call `dispatch` with the returning value.
     *
     * @param {Function} dispatch The redux dispatch function.
     * @param {HTMLElement} element The element instance.
     *
     * @return {Object} Key-value map of event names and their listeners.
     */
    static mapDispatchToEvents(dispatch, element) {
        return bindActionCreators(
            {
                addTask(event) {
                    return {
                        type: 'ADD_TASK',
                        task: event.detail
                    };
                },
                updateTaskDone(event) {
                    return {
                        type: 'UPDATE_TASK_DONE',
                        index: event.detail.index,
                        done: event.detail.done
                    };
                },
                removeTask(event) {
                    return {
                        type: 'REMOVE_TASK',
                        index: event.detail
                    };
                }
            },
            dispatch
        );
    }
}

customElements.define('redux-todo', ReduxTodo);
import {dedupingMixin} from '@polymer/polymer/lib/utils/mixin.js';
import ReduxMixin from 'mixins/redux';

let internalAnotherMixin = (base) =>
  class extends ReduxMixin(base) {
    static get properties() {
        return {
            another:{
                type:Boolean,
                value: true
            } 
        };
    }
    constructor(){
        super();
        console.log("Hello from another constructor");
        //this.another = true;
    }

    static mapStateToProps(state, element) {
        console.log('mapping props from another-mixin');
        console.dir(this);
        console.dir(state);
        return {
            another: state.another
        };
    }

  }

  export const AnotherMixin = dedupingMixin(internalAnotherMixin);
import {dedupingMixin} from '@polymer/polymer/lib/utils/mixin.js';

let internalExtraMixin = (base) =>
  class extends base {
    static get properties() {
        return {
            extras: String
        };
    }
    constructor(){
        super();
        console.log("Hello from extras constructor");
        //this.extras = "Hello world";
    }
  }

  export const ExtraMixin = dedupingMixin(internalExtraMixin);
...
class ReduxTodo extends AnotherMixin(ExtraMixin((TodoApp))) {
...
}
编辑2:
对于这个重复导入问题,如果我只是从mixin中删除ReduxMixin并将其保留在redux todo.js中(它是从那里继承的,因此它也可以在mixin中工作)

redux
中,您可以使用
connect(mapstatetops)(您的组件)
Hello我的评论可能很愚蠢,但据我所知,它只在react redux中可用,我没有使用该库。