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

Automatically bind store methods #100

Merged
merged 3 commits into from
Nov 20, 2014
Merged
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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ The following command installs reflux as a bower component that can be used in t

bower install reflux

### ES5

Like React, Reflux depends on an es5-shim for older browsers. The es5-shim.js from [kriskowal's es5-shim](https://github.com/kriskowal/es5-shim) provides everything required.

## Usage

For a full example check the [`test/index.js`](test/index.js) file.
Expand Down
1 change: 1 addition & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module.exports = function(config) {
],

files: [
'test/shims/phantomjs-shims.js',
'test/*.spec.js'
],

Expand Down
13 changes: 13 additions & 0 deletions src/bindMethods.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = function(store, definition) {
for (var name in definition) {
var property = definition[name];

if (typeof property !== 'function' || !definition.hasOwnProperty(name)) {
continue;
}

store[name] = property.bind(store);
}

return store;
};
4 changes: 3 additions & 1 deletion src/createStore.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
var _ = require('./utils'),
Reflux = require('../src'),
Keep = require('./Keep'),
allowed = {preEmit:1,shouldEmit:1};
allowed = {preEmit:1,shouldEmit:1},
bindMethods = require('./bindMethods');

/**
* Creates an event emitting Data Store. It is mixed in with functions
Expand Down Expand Up @@ -42,6 +43,7 @@ module.exports = function(definition) {
_.extend(Store.prototype, Reflux.ListenerMethods, Reflux.PublisherMethods, definition);

var store = new Store();
bindMethods(store, definition);
Keep.createdStores.push(store);

return store;
Expand Down
11 changes: 11 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,14 @@ exports.nextTick = function(nextTick) {
* Provides the set of created actions and stores for introspection
*/
exports.__keep = require('./Keep');

/**
* Warn if Function.prototype.bind not available
*/
if (!Function.prototype.bind) {
console.error(
'Function.prototype.bind not available. ' +
'ES5 shim required. ' +
'https://github.com/spoike/refluxjs#es5'
);
}
16 changes: 16 additions & 0 deletions test/creatingStores.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,4 +303,20 @@ describe('Creating stores', function() {
assert.isUndefined(Reflux.ListenerMethods.trigger);
});

describe('store methods', function() {
var store;

beforeEach(function() {
store = Reflux.createStore({
reflect: function() {
return this;
}
});
});

it('should be bound to store instance', function() {
var reflect = store.reflect;
return assert.equal(store, reflect());
});
});
});
36 changes: 36 additions & 0 deletions test/shims/phantomjs-shims.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// From https://github.com/facebook/react/blob/master/src/test/phantomjs-shims.js
(function() {

var Ap = Array.prototype;
var slice = Ap.slice;
var Fp = Function.prototype;

if (!Fp.bind) {
// PhantomJS doesn't support Function.prototype.bind natively, so
// polyfill it whenever this module is required.
Fp.bind = function(context) {
var func = this;
var args = slice.call(arguments, 1);

function bound() {
var invokedAsConstructor = func.prototype && (this instanceof func);
return func.apply(
// Ignore the context parameter when invoking the bound function
// as a constructor. Note that this includes not only constructor
// invocations using the new keyword but also calls to base class
// constructors such as BaseClass.call(this, ...) or super(...).
!invokedAsConstructor && context || this,
args.concat(slice.call(arguments))
);
}

// The bound function must share the .prototype of the unbound
// function so that any object created by one constructor will count
// as an instance of both constructors.
bound.prototype = func.prototype;

return bound;
};
}

})();