Skip to content

Commit

Permalink
Merge pull request #100 from rymohr/bind-store-methods
Browse files Browse the repository at this point in the history
Automatically bind store methods
  • Loading branch information
spoike committed Nov 20, 2014
2 parents e56bd36 + 6d179e6 commit 06e1140
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 1 deletion.
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;
};
}

})();

0 comments on commit 06e1140

Please sign in to comment.