Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bind dispatch on events #2

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
16 changes: 13 additions & 3 deletions src/connector.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { bindActionCreators } from 'redux'

import {
shallowEqual,
wrapActionCreators
} 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 @@ -24,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 @@ -35,7 +39,7 @@ const connector = (_mapState = defaultMapState, mapDispatch = defaultMapDispatch
const initData = {}
const mapData = {
...mapState(this.$$store.getState()),
...wrapActionCreators(mapDispatch)(this.$$store.dispatch)
...bindActionCreators(mapDispatch, this.$$store.dispatch)
}

Object.keys(mapData).forEach(key => {
Expand All @@ -47,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
4 changes: 1 addition & 3 deletions src/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import shallowEqual from './shallowEqual'
import wrapActionCreators from './wrapActionCreators'

export {
shallowEqual,
wrapActionCreators
shallowEqual
}
7 changes: 0 additions & 7 deletions src/utils/wrapActionCreators.js

This file was deleted.

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