Skip to content

Commit

Permalink
Add support for event dispatch binding
Browse files Browse the repository at this point in the history
  • Loading branch information
LeMisterV committed Dec 7, 2017
1 parent 89f8eba commit 93e6f2e
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 9 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ Here our state looks something like `{ status: 'foobar' }`
methods: {
doMagic: function () {
this.createAction()
},
doMagic2: function () {
this.$emit('customevent')
}
}
}
Expand All @@ -103,6 +106,10 @@ Here our state looks something like `{ status: 'foobar' }`

const mapDispatch = { createAction }

const mapEventDispatch = {
customevent: createAction
}

export default connect(mapState, mapDispatch)(component)
</script>
```
Expand Down
21 changes: 14 additions & 7 deletions dist/revux.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,19 @@ function shallowEqual(objA, objB) {
return true;
}

var wrapActionCreators = function wrapActionCreators(actionCreators) {
return function (dispatch) {
return redux.bindActionCreators(actionCreators, dispatch);
};
};

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var defaultMapState = function defaultMapState() {
return {};
};
var defaultMapDispatch = {};
var defaultEventDispatch = {};

var forEach = function forEach(obj, iterator) {
return Object.keys(obj).forEach(function (key) {
return iterator(key, obj[key]);
});
};

var normalizeMapState = function normalizeMapState(mapState) {
if (typeof mapState === 'function') {
Expand All @@ -103,6 +104,7 @@ var connector = function connector() {
var _mapState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultMapState;

var mapDispatch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultMapDispatch;
var eventDispatch = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultEventDispatch;
return function (component) {
var mapState = normalizeMapState(_mapState);
return {
Expand All @@ -112,7 +114,7 @@ var connector = function connector() {

data: function data() {
var initData = {};
var mapData = _extends({}, mapState(this.$$store.getState()), wrapActionCreators(mapDispatch)(this.$$store.dispatch));
var mapData = _extends({}, mapState(this.$$store.getState()), redux.bindActionCreators(mapDispatch, this.$$store.dispatch));

Object.keys(mapData).forEach(function (key) {
initData[key] = mapData[key];
Expand All @@ -124,6 +126,11 @@ var connector = function connector() {
var _this = this;

var vm = this;

forEach(redux.bindActionCreators(eventDispatch, this.$$store.dispatch), function (eventName, dispatcher) {
return vm.$on(eventName, dispatcher);
});

var getMappedState = function getMappedState(state) {
return mapState(state);
};
Expand Down
13 changes: 11 additions & 2 deletions src/connector.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import { bindActionCreators } from 'redux'

import {
shallowEqual,
} from './utils'
} from './utils/index'

const defaultMapState = () => ({})
const defaultMapDispatch = {}
const defaultEventDispatch = {}

const forEach = (obj, iterator) => Object.keys(obj).forEach(key => iterator(key, obj[key]))

const normalizeMapState = mapState => {
if (typeof mapState === 'function') {
Expand All @@ -25,7 +28,7 @@ const normalizeMapState = mapState => {
}
}

const connector = (_mapState = defaultMapState, mapDispatch = defaultMapDispatch) => component => {
const connector = (_mapState = defaultMapState, mapDispatch = defaultMapDispatch, eventDispatch = defaultEventDispatch) => component => {
const mapState = normalizeMapState(_mapState);
return {
name: `connect-${component.name}`,
Expand All @@ -48,6 +51,12 @@ const connector = (_mapState = defaultMapState, mapDispatch = defaultMapDispatch

created () {
const vm = this

forEach(
bindActionCreators(eventDispatch, this.$$store.dispatch),
(eventName, dispatcher) => vm.$on(eventName, dispatcher)
)

const getMappedState = state => mapState(state)

const observeStore = (store, select, onChange) => {
Expand Down
49 changes: 49 additions & 0 deletions test/connector.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,55 @@ describe('Connector', () => {

})

describe('events mapping', () => {
let dispatchStub
const originalDispatch = store.dispatch
beforeEach(() => {
dispatchStub = sinon.stub().returns()
store.dispatch = dispatchStub
})

afterEach(() => {
store.dispatch = originalDispatch
})

it('should map actions on events on connected component', () => {
let vm
let actionCreator = sinon.stub().returns({type: 'DO_THIS'});

const baseComponent = {
created () {
vm = this
},
render () {}
}

const mapEvents = {
eventName: actionCreator
}

new Vue({
template: `<connected />`,
provide: {
$$store: store
},
components: {
connected: {
template: `<connected-component/>`,
components: {
connectedComponent: connector(undefined, undefined, mapEvents)(baseComponent)
}
}
}
}).$mount()

vm.$emit('eventName');

expect(actionCreator.called, 'action creator was not called').to.be.true
expect(store.dispatch.called, 'dispatch was not called').to.be.true
})
})

it('should override and use mapDispatch value if the same key is defined both in mapState and mapDispatch', () => {
let vm
const baseComponent = {
Expand Down

0 comments on commit 93e6f2e

Please sign in to comment.