Permalink
Browse files

Merge pull request #1110 from braddunbar/off

Fix #1105 - Add convenience overloads for `off`.
  • Loading branch information...
2 parents e2e0a09 + fb27097 commit 5f41b88764060c9996ebdc0b3560e984d11c17ca @jashkenas jashkenas committed Mar 19, 2012
Showing with 60 additions and 37 deletions.
  1. +16 −15 backbone.js
  2. +26 −22 index.html
  3. +18 −0 test/events.js
View
@@ -111,22 +111,23 @@
// event. If `events` is null, removes all bound callbacks for all events.
off: function(events, callback, context) {
var event, calls, node, tail, cb, ctx;
- if (!events) {
+ if (!(calls = this._callbacks)) return;
+ if (!(events || callback || context)) {
delete this._callbacks;
- } else if (calls = this._callbacks) {
- events = events.split(eventSplitter);
- while (event = events.shift()) {
- node = calls[event];
- delete calls[event];
- if (!callback || !node) continue;
- // Create a new list, omitting the indicated callbacks.
- tail = node.tail;
- while ((node = node.next) !== tail) {
- cb = node.callback;
- ctx = node.context;
- if (cb !== callback || (context && ctx !== context)) {
- this.on(event, cb, ctx);
- }
+ return this;
+ }
+ events = events ? events.split(eventSplitter) : _.keys(calls);
+ while (event = events.shift()) {
+ node = calls[event];
+ delete calls[event];
+ if (!node || !(callback || context)) continue;
+ // Create a new list, omitting the indicated callbacks.
+ tail = node.tail;
+ while ((node = node.next) !== tail) {
+ cb = node.callback;
+ ctx = node.context;
+ if ((callback && cb !== callback) || (context && ctx !== context)) {
+ this.on(event, cb, ctx);
}
}
}
View
@@ -617,6 +617,10 @@ <h2 id="Events">Backbone.Events</h2>
object.off("change"); // Removes all "change" callbacks.
+object.off(null, onChange); // Removes the onChange callback for all events.
+
+object.off(null, null, context); // Removes all callbacks for context for all events.
+
object.off(); // Removes all callbacks on object.
</pre>
@@ -1914,7 +1918,7 @@ <h2 id="Sync">Backbone.sync</h2>
(<a href="#Collection#fetch">Collection#fetch</a>), send down an array
of model attribute objects.
</p>
-
+
<p>
The <b>sync</b> function may be overriden globally as <tt>Backbone.sync</tt>,
or at a finer-grained level, by adding a <tt>sync</tt> function to a Backbone
@@ -2557,15 +2561,15 @@ <h2 id="examples-stripe">Stripe</h2>
<img src="docs/images/stripe.png" alt="Stripe" class="example_image" />
</a>
</div>
-
+
<h2 id="examples-airbnb">Airbnb Mobile</h2>
<p>
- <a href="http://airbnb.com">Airbnb</a> used Backbone.js and
- <a href="http://coffeescript.org">CoffeeScript</a> to quickly build
- <a href="http://m.airbnb.com">Airbnb Mobile</a>
- in six weeks with a team of three. The mobile version of Airbnb lets you
- discover and book rental spaces directly from your phone: from a private
+ <a href="http://airbnb.com">Airbnb</a> used Backbone.js and
+ <a href="http://coffeescript.org">CoffeeScript</a> to quickly build
+ <a href="http://m.airbnb.com">Airbnb Mobile</a>
+ in six weeks with a team of three. The mobile version of Airbnb lets you
+ discover and book rental spaces directly from your phone: from a private
apartment to a private island...
</p>
@@ -2824,15 +2828,15 @@ <h2 id="examples-animoto">Animoto</h2>
<img src="docs/images/animoto.png" alt="Tzigla" class="Animoto Video Editor" />
</a>
</div>
-
+
<h2 id="examples-chaincal">ChainCal</h2>
<p>
- <a href="http://chaincalapp.com/">ChainCal</a>
- is an iPhone app that helps you to track your daily goals in a
- minimalist, visual way. The app is written almost entirely in <a href="http://coffeescript.org/">CoffeeScript</a>,
- Backbone handles the models, collections and views, and persistence is
- done with a Backbone.sync localStorage adapter. Templates are written in
+ <a href="http://chaincalapp.com/">ChainCal</a>
+ is an iPhone app that helps you to track your daily goals in a
+ minimalist, visual way. The app is written almost entirely in <a href="http://coffeescript.org/">CoffeeScript</a>,
+ Backbone handles the models, collections and views, and persistence is
+ done with a Backbone.sync localStorage adapter. Templates are written in
<a href="https://github.com/sstephenson/eco">Eco</a> and the app is packaged with <a href="http://brunch.io/">Brunch</a> and deployed with <a href="http://phonegap.com/">Phonegap</a>.
</p>
@@ -2841,16 +2845,16 @@ <h2 id="examples-chaincal">ChainCal</h2>
<img src="docs/images/chaincal.png" alt="ChainCal" class="example_image" />
</a>
</div>
-
+
<h2 id="examples-attictv">AtticTV</h2>
<p>
- <a href="http://attictv.com/">AtticTV</a> is MTV for the Youtube Generation:
- kick back and relax while watching the best
- music videos of your favorite genre. The videos are synced across the
- world, so, you're never watching alone on AtticTV. AtticTV is served by
- <a href="http://nodejs.org/">NodeJS</a> written in <a href="http://coffeescript.org/">CoffeeScript</a> with <a href="http://socket.io/">Socket.IO</a> as data transport. The
- frontend is built with Backbone.js with pushstate support, <a href="http://jquery.com/">jQuery</a>, and
+ <a href="http://attictv.com/">AtticTV</a> is MTV for the Youtube Generation:
+ kick back and relax while watching the best
+ music videos of your favorite genre. The videos are synced across the
+ world, so, you're never watching alone on AtticTV. AtticTV is served by
+ <a href="http://nodejs.org/">NodeJS</a> written in <a href="http://coffeescript.org/">CoffeeScript</a> with <a href="http://socket.io/">Socket.IO</a> as data transport. The
+ frontend is built with Backbone.js with pushstate support, <a href="http://jquery.com/">jQuery</a>, and
<a href="http://jade-lang.com/">Jade templates</a>.
</p>
@@ -3146,8 +3150,8 @@ <h2 id="faq">F.A.Q.</h2>
<p>You have to <a href="http://mathiasbynens.be/notes/etago">escape</a>
<tt>&lt;/</tt> within the JSON string, to prevent javascript injection
- attacks.
-
+ attacks.
+
<p id="FAQ-extending">
<b class="header">Extending Backbone</b>
<br />
View
@@ -149,4 +149,22 @@ $(document).ready(function() {
_.extend({}, Backbone.Events).bind('test').trigger('test');
});
+ test("remove all events for a specific context", 4, function() {
+ var obj = _.extend({}, Backbone.Events);
+ obj.on('x y all', function() { ok(true); });
+ obj.on('x y all', function() { ok(false); }, obj);
+ obj.off(null, null, obj);
+ obj.trigger('x y');
+ });
+
+ test("remove all events for a specific callback", 4, function() {
+ var obj = _.extend({}, Backbone.Events);
+ var success = function() { ok(true); };
+ var fail = function() { ok(false); };
+ obj.on('x y all', success);
+ obj.on('x y all', fail);
+ obj.off(null, fail);
+ obj.trigger('x y');
+ });
+
});

0 comments on commit 5f41b88

Please sign in to comment.