mirror of
https://github.com/jashkenas/backbone.git
synced 2026-04-30 03:00:06 -04:00
Implement once with minimal change to other Events methods.
This commit is contained in:
42
backbone.js
42
backbone.js
@@ -67,9 +67,6 @@
|
||||
// Regular expression used to split event strings
|
||||
var eventSplitter = /\s+/;
|
||||
|
||||
// Internal flag used to set event callbacks `once`.
|
||||
var once = false;
|
||||
|
||||
// A module that can be mixed in to *any object* in order to provide it with
|
||||
// custom events. You may bind with `on` or remove with `off` callback functions
|
||||
// to an event; `trigger`-ing an event fires all callbacks in succession.
|
||||
@@ -99,7 +96,7 @@
|
||||
|
||||
while (event = events.shift()) {
|
||||
list = calls[event] || (calls[event] = []);
|
||||
list.push(callback, context, once ? {} : null);
|
||||
list.push(callback, context);
|
||||
}
|
||||
|
||||
return this;
|
||||
@@ -108,9 +105,22 @@
|
||||
// Bind events to only be triggered a single time. After the first time
|
||||
// the callback is invoked, it will be removed.
|
||||
once: function(events, callback, context) {
|
||||
once = true;
|
||||
this.on(events, callback, context);
|
||||
once = false;
|
||||
if (_.isObject(events)) {
|
||||
for (var key in events) {
|
||||
this.once(key, events[key], callback);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
_.each(events.split(eventSplitter), function(event) {
|
||||
var f = _.once(function() {
|
||||
this.off(event, f);
|
||||
callback.apply(context, arguments);
|
||||
});
|
||||
f._callback = callback;
|
||||
this.on(event, f, this);
|
||||
}, this);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -143,9 +153,12 @@
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = list.length - 3; i >= 0; i -= 3) {
|
||||
if (!(callback && list[i] !== callback || context && list[i + 1] !== context)) {
|
||||
list.splice(i, 3);
|
||||
for (i = list.length - 2; i >= 0; i -= 2) {
|
||||
if (!(
|
||||
callback && list[i] !== callback && list[i]._callback !== callback
|
||||
|| context && list[i + 1] !== context
|
||||
)) {
|
||||
list.splice(i, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,18 +192,15 @@
|
||||
|
||||
// Execute event callbacks.
|
||||
if (list) {
|
||||
for (i = 0, length = list.length; i < length; i += 3) {
|
||||
callback = list[i], context = list[i + 1], onced = list[i + 2];
|
||||
if (onced) calls[event].splice(i, 3);
|
||||
if (!onced || !onced.dead) callback.apply(context || this, rest);
|
||||
if (onced) onced.dead = true;
|
||||
for (i = 0, length = list.length; i < length; i += 2) {
|
||||
list[i].apply(list[i + 1] || this, rest);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute "all" callbacks.
|
||||
if (all) {
|
||||
args = [event].concat(rest);
|
||||
for (i = 0, length = all.length; i < length; i += 3) {
|
||||
for (i = 0, length = all.length; i < length; i += 2) {
|
||||
all[i].apply(all[i + 1] || this, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ $(document).ready(function() {
|
||||
test("once", 2, function() {
|
||||
// Same as the previous test, but we use once rather than having to explicitly unbind
|
||||
var obj = { counterA: 0, counterB: 0 };
|
||||
_.extend(obj,Backbone.Events);
|
||||
_.extend(obj, Backbone.Events);
|
||||
var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };
|
||||
var incrB = function(){ obj.counterB += 1 };
|
||||
obj.once('event', incrA);
|
||||
@@ -310,4 +310,21 @@ $(document).ready(function() {
|
||||
obj.trigger('async');
|
||||
});
|
||||
|
||||
test("Off during iteration with once.", 2, function() {
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
var f = function(){ this.off('event', f); };
|
||||
obj.on('event', f);
|
||||
obj.once('event', function(){});
|
||||
obj.on('event', function(){ ok(true); });
|
||||
|
||||
obj.trigger('event');
|
||||
obj.trigger('event');
|
||||
});
|
||||
|
||||
test("once with multiple events.", 2, function() {
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
obj.once('x y', function() { ok(true); });
|
||||
obj.trigger('x y');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user