diff --git a/backbone.js b/backbone.js index 72d5e9dd..1a77c4dd 100644 --- a/backbone.js +++ b/backbone.js @@ -60,19 +60,19 @@ // ----------------- // A module that can be mixed in to *any object* in order to provide it with - // custom events. You may `bind` or `unbind` a callback function to an event; - // `trigger`-ing an event fires all callbacks in succession. + // 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. // // var object = {}; // _.extend(object, Backbone.Events); - // object.bind('expand', function(){ alert('expanded'); }); + // object.on('expand', function(){ alert('expanded'); }); // object.trigger('expand'); // Backbone.Events = { // Bind an event, specified by a string name, `ev`, to a `callback` // function. Passing `"all"` will bind the callback to all events fired. - bind : function(ev, callback, context) { + on : function(ev, callback, context) { var calls = this._callbacks || (this._callbacks = {}); var list = calls[ev] || (calls[ev] = {}); var tail = list.tail || (list.tail = list.next = {}); @@ -85,7 +85,7 @@ // Remove one or many callbacks. If `context` is null, removes all callbacks // with that function. If `callback` is null, removes all callbacks for the // event. If `ev` is null, removes all bound callbacks for all events. - unbind : function(ev, callback, context) { + off : function(ev, callback, context) { var calls, node; if (!ev) { delete this._callbacks; @@ -96,7 +96,7 @@ while ((node = node.next) && node.next) { if (node.callback === callback && (!context || node.context === context)) continue; - this.bind(ev, node.callback, node.context); + this.on(ev, node.callback, node.context); } } return this; @@ -126,6 +126,10 @@ }; + // Aliases for backwards compatibility. + Backbone.Events.bind = Backbone.Events.on; + Backbone.Events.unbind = Backbone.Events.off; + // Backbone.Model // -------------- @@ -438,7 +442,7 @@ } this._byCid[model.cid] = model; if (hasId) this._byId[model.id] = model; - model.bind('all', this._onModelEvent, this); + model.on('all', this._onModelEvent, this); } this.length += length; i = options.at != null ? options.at : this.models.length; @@ -596,7 +600,7 @@ if (this == model.collection) { delete model.collection; } - model.unbind('all', this._onModelEvent, this); + model.off('all', this._onModelEvent, this); }, // Internal method called every time a model in the set fires an event. diff --git a/test/events.js b/test/events.js index d4cde4c2..2c77d021 100644 --- a/test/events.js +++ b/test/events.js @@ -2,10 +2,10 @@ $(document).ready(function() { module("Backbone.Events"); - test("Events: bind and trigger", function() { + test("Events: on and trigger", function() { var obj = { counter: 0 }; _.extend(obj,Backbone.Events); - obj.bind('event', function() { obj.counter += 1; }); + obj.on('event', function() { obj.counter += 1; }); obj.trigger('event'); equals(obj.counter,1,'counter should be incremented.'); obj.trigger('event'); @@ -15,13 +15,13 @@ $(document).ready(function() { equals(obj.counter, 5, 'counter should be incremented five times.'); }); - test("Events: bind, then unbind all functions", function() { + test("Events: on, then unbind all functions", function() { var obj = { counter: 0 }; _.extend(obj,Backbone.Events); var callback = function() { obj.counter += 1; }; - obj.bind('event', callback); + obj.on('event', callback); obj.trigger('event'); - obj.unbind('event'); + obj.off('event'); obj.trigger('event'); equals(obj.counter, 1, 'counter should have only been incremented once.'); }); @@ -30,10 +30,10 @@ $(document).ready(function() { var obj = { counterA: 0, counterB: 0 }; _.extend(obj,Backbone.Events); var callback = function() { obj.counterA += 1; }; - obj.bind('event', callback); - obj.bind('event', function() { obj.counterB += 1; }); + obj.on('event', callback); + obj.on('event', function() { obj.counterB += 1; }); obj.trigger('event'); - obj.unbind('event', callback); + obj.off('event', callback); obj.trigger('event'); equals(obj.counterA, 1, 'counterA should have only been incremented once.'); equals(obj.counterB, 2, 'counterB should have been incremented twice.'); diff --git a/test/model.js b/test/model.js index 2e049e90..afac04f7 100644 --- a/test/model.js +++ b/test/model.js @@ -89,8 +89,9 @@ $(document).ready(function() { test("Model: url when using urlRoot as a function to determine urlRoot at runtime", function() { var Model = Backbone.Model.extend({ - urlRoot: function() { return '/nested/' + this.get('parent_id') + '/collection'} - // looks better in coffeescript: urlRoot: => "/nested/#{@get('parent_id')}/collection" + urlRoot: function() { + return '/nested/' + this.get('parent_id') + '/collection'; + } }); var model = new Model({parent_id: 1}); @@ -167,7 +168,7 @@ $(document).ready(function() { attrs = {id: 'id', foo: 1, bar: 2, baz: 3}; a = new Backbone.Model(attrs); var changeCount = 0; - a.bind("change:foo", function() { changeCount += 1; }); + a.on("change:foo", function() { changeCount += 1; }); a.set({'foo': 2}); ok(a.get('foo') == 2, "Foo should have changed."); ok(changeCount == 1, "Change count should have incremented."); @@ -191,7 +192,7 @@ $(document).ready(function() { var i = 0; var counter = function(){ i++; }; var model = new Backbone.Model({a: 1}); - model.bind("change:a", counter); + model.on("change:a", counter); model.set({a: 2}); model.unset('a'); model.unset('a'); @@ -228,8 +229,8 @@ $(document).ready(function() { test("Model: clear", function() { var changed; var model = new Backbone.Model({id: 1, name : "Model"}); - model.bind("change:name", function(){ changed = true; }); - model.bind("change", function() { + model.on("change:name", function(){ changed = true; }); + model.on("change", function() { var changedAttrs = model.changedAttributes(); ok('name' in changedAttrs); }); @@ -264,7 +265,7 @@ $(document).ready(function() { test("Model: change, hasChanged, changedAttributes, previous, previousAttributes", function() { var model = new Backbone.Model({name : "Tim", age : 10}); equals(model.changedAttributes(), false); - model.bind('change', function() { + model.on('change', function() { ok(model.hasChanged('name'), 'name changed'); ok(!model.hasChanged('age'), 'age did not'); ok(_.isEqual(model.changedAttributes(), {name : 'Rob'}), 'changedAttributes returns the changed attrs'); @@ -281,7 +282,7 @@ $(document).ready(function() { test("Model: change with options", function() { var value; var model = new Backbone.Model({name: 'Rob'}); - model.bind('change', function(model, options) { + model.on('change', function(model, options) { value = options.prefix + model.get('name'); }); model.set({name: 'Bob'}, {silent: true}); @@ -295,14 +296,14 @@ $(document).ready(function() { var changed = 0; var attrs = {id: 1, label: 'c'}; var obj = new Backbone.Model(attrs); - obj.bind('change', function() { changed += 1; }); + obj.on('change', function() { changed += 1; }); obj.set(attrs); equals(changed, 0); }); test("Model: save within change event", function () { var model = new Backbone.Model({firstName : "Taylor", lastName: "Swift"}); - model.bind('change', function () { + model.on('change', function () { model.save(); ok(_.isEqual(lastRequest[1], model)); }); @@ -355,7 +356,7 @@ $(document).ready(function() { model.validate = function(attrs) { if (attrs.admin) return "Can't change admin status."; }; - model.bind('error', function(model, error) { + model.on('error', function(model, error) { lastError = error; }); var result = model.set({a: 100}); @@ -404,7 +405,7 @@ $(document).ready(function() { var callback = function(model, error) { lastError = error; }; - model.bind('error', function(model, error) { + model.on('error', function(model, error) { boundError = true; }); var result = model.set({a: 100}, {error: callback}); @@ -457,7 +458,7 @@ $(document).ready(function() { test("Model: Nested change events don't clobber previous attributes", function() { var A = Backbone.Model.extend({ initialize: function() { - this.bind("change:state", function(a, newState) { + this.on("change:state", function(a, newState) { equals(a.previous('state'), undefined); equals(newState, 'hello'); // Fire a nested change event. @@ -468,7 +469,7 @@ $(document).ready(function() { var B = Backbone.Model.extend({ initialize: function() { - this.get("a").bind("change:state", function(a, newState) { + this.get("a").on("change:state", function(a, newState) { equals(a.previous('state'), undefined); equals(newState, 'hello'); }); @@ -482,7 +483,7 @@ $(document).ready(function() { test("Model: Multiple nested calls to set", function() { var counter = 0, model = new Backbone.Model({}); - model.bind('change', function() { + model.on('change', function() { counter++; model.set({b: 1}); model.set({a: 1}); @@ -494,10 +495,10 @@ $(document).ready(function() { test("hasChanged/set should use same comparison", function() { expect(2); var changed = 0, model = new Backbone.Model({a: null}); - model.bind('change', function() { + model.on('change', function() { ok(this.hasChanged('a')); }) - .bind('change:a', function() { + .on('change:a', function() { changed++; }) .set({a: undefined});