backbone-signal
Advanced tools
Comparing version 0.1.0 to 0.1.1
// Copyright by Brian Takita, 2013 Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php | ||
(function() { | ||
var root = typeof window !== 'undefined' ? window : global; | ||
function Signal(target, attributeName) { | ||
@@ -154,4 +153,4 @@ this.target = target; | ||
}, | ||
unbind: function(listener) { | ||
listener.stopListening(this.target, this.attributeName && this.changeKey); | ||
unbind: function(listener, cb) { | ||
listener.stopListening(this.target, this.attributeName && this.changeKey, cb); | ||
return this; | ||
@@ -204,3 +203,3 @@ }, | ||
if (value) { | ||
listener.stopListening(signal.target, signal.changeKey, getTruthyOnceCb); | ||
signal.unbind(listener, getTruthyOnceCb); | ||
cb.apply(signal, arguments); | ||
@@ -212,4 +211,4 @@ } | ||
return function getFalsyOnceCb(model, value) { | ||
if (value) { | ||
listener.stopListening(signal.target, signal.changeKey, getFalsyOnceCb); | ||
if (!value) { | ||
signal.unbind(listener, getFalsyOnceCb); | ||
cb.apply(signal, arguments); | ||
@@ -222,3 +221,3 @@ } | ||
if (value !== undefined && value !== null) { | ||
listener.stopListening(signal.target, signal.changeKey, getDefinedOnceCb); | ||
signal.unbind(listener, getDefinedOnceCb); | ||
cb.apply(signal, arguments); | ||
@@ -240,6 +239,7 @@ } | ||
_.extend(Backbone.Model.prototype, api); | ||
var module = root.module; | ||
if (module && module.exports) { | ||
module.exports = api; | ||
if (typeof module !== "undefined") { | ||
if (module.exports) { | ||
module.exports = api; | ||
} | ||
} | ||
})(); |
@@ -7,3 +7,3 @@ { | ||
"main": "backbone-signal.js", | ||
"version": "0.1.0", | ||
"version": "0.1.1", | ||
"license": "MIT", | ||
@@ -10,0 +10,0 @@ "repository": { |
102
README.md
backbone-signal | ||
=============== | ||
A rich Signal & Slots api using Backbone. | ||
A rich Signal & Slots (Reactive Programming) api on Backbone Models. It is composable, allows you to encapsulate loader logic, | ||
and have fine grained control over listening to change events. | ||
# Usage | ||
```javascript | ||
// backbone-signal extends Backbone.Model | ||
var app = new Backbone.Model(); | ||
// The block is called with load when the value of the signal is null. | ||
var userSignal = app.signal("user").setLoader(function() { | ||
userSignal.set({ | ||
name: "..." | ||
}); | ||
}); | ||
console.info("Let's see some friends"); | ||
// userSignal.value() is null so the loader is called | ||
userSignal.load().getTruthy(app, function(app, user) { | ||
console.info("Hello " + user.name); | ||
}); | ||
userSignal.set({ | ||
name: "Jane" | ||
}); | ||
// userSignal.value() is not null so the loader is not called | ||
userSignal.load().getTruthy(app, function(app, user) { | ||
console.info("Nice to see you"); | ||
}); | ||
userSignal.set({ | ||
name: "Joe" | ||
}); | ||
userSignal.unset(); | ||
``` | ||
The console ouput is: | ||
Let's see some friends | ||
Hello ... | ||
Hello Jane | ||
Nice to see you | ||
Hello Joe | ||
Nice to see you | ||
First, notice setLoader. The loader is called when load() if first called because userSignal.value() == null (== undefined as well). The second time load() is called, the loader is not called, since userSignal.value() is not == null. | ||
We are calling getTruthy on the userSignal two times, one for "Hello " + user.name and one for "Nice to see you". The callback is invoked when the value is [Truthy](http://www.sitepoint.com/javascript-truthy-falsy/). So when userSignal.unset is called, the callbacks are not invoked. | ||
What is nice about having a dedicated signal object is that you can bind to it even when it's value is undefined, thereby avoiding order dependencies and simplyfying your logic. | ||
backbone-signal also utilizes Backbone's listenTo and listenToOnce methods, which make it easy to clean up by calling stopListening on the listener. | ||
backbone-signal is being used in [www.rundavoo.com](http://www.rundavoo.com) and has been fun to use, especially with [node.js](http://nodejs.org/) & [Browserify](http://browserify.org/). It's been a pleasure using a lightweight unframework to freely structure the dataflow logic of the site. | ||
#API | ||
## Loading/Unloading | ||
* load - Invokes the loader when the value is not defined | ||
* forceLoad - Invokes the loader (regardless if the value is defined) | ||
* reload - Unsets the value then invokes the loader | ||
* unload - Invokes the unloader | ||
* setLoader - Sets the Loader callback | ||
* unsetLoader - Unsets the Loader callback | ||
* setUnloader - Sets the Unloader callback | ||
* unsetUnloader - Unsets the Unloader callback | ||
## Setters | ||
* set - Sets the value with the argument | ||
* unset - Unets the value | ||
* value - Returns the value | ||
## Getters/Listeners | ||
* get - Invoke the callback immeditately and on any additional changes to the value | ||
* listen - Listen to any additional changes to the value (does not invoke the callback immeditately) | ||
* getOnce - Invoke the callback immeditately one time | ||
* listenOnce - Listen to any additional changes to the value one time | ||
* getTruthy - Invoke the callback immeditately and on any additional changes to the value if the value is truthy | ||
* listenTruthy - Listen to any additional changes to the value if the value is truthy | ||
* getTruthyOnce - Invoke the callback immeditately or on any additional changes to the value if the value is truthy one time only | ||
* listenTruthyOnce - Listen to any additional changes to the value if the value is truthy one time only | ||
* getFalsy- Invoke the callback immeditately and on any additional changes to the value if the value is falsy | ||
* listenFalsy - Listen to any additional changes to the value if the value is falsy | ||
* getFalsyOnce - Invoke the callback immeditately or on any additional changes to the value if the value is falsy one time only | ||
* listenFalsyOnce - Listen to any additional changes to the value if the value is falsy one time only | ||
* getDefined- Invoke the callback immeditately and on any additional changes to the value if the value is defined | ||
* listenDefined - Listen to any additional changes to the value if the value is defined | ||
* getDefinedOnce - Invoke the callback immeditately or on any additional changes to the value if the value is defined one time only | ||
* listenDefinedOnce - Listen to any additional changes to the value if the value is defined one time only | ||
* unbind - Unbinds the given object from the callback | ||
* loading | ||
* isLoading | ||
# Blog Posts | ||
http://briantakita.com/articles/backbone-signal-practical-reactive-programming-in-javascript/ |
12144
106