From 6a0ac930863ab4f1cf107d879aa658495372cb2b Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Thu, 2 Dec 2010 09:31:55 -0500 Subject: [PATCH] Fixing Issue #109 -- ignore 'add' and 'remove' events that originate from models shared with other collections. --- backbone.js | 6 ++++-- test/collection.js | 27 ++++++++++++++++++--------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/backbone.js b/backbone.js index 04fe46ea..640fbb83 100644 --- a/backbone.js +++ b/backbone.js @@ -564,8 +564,10 @@ // Internal method called every time a model in the set fires an event. // Sets need to update their indexes when models change ids. All other - // events simply proxy through. - _onModelEvent : function(ev, model) { + // events simply proxy through. "add" and "remove" events that originate + // in other collections are ignored. + _onModelEvent : function(ev, model, collection) { + if ((ev == 'add' || ev == 'remove') && collection != this) return; if (ev === 'change:id') { delete this._byId[model.previous('id')]; this._byId[model.id] = model; diff --git a/test/collection.js b/test/collection.js index 4fccb8d8..3f2f84be 100644 --- a/test/collection.js +++ b/test/collection.js @@ -8,12 +8,13 @@ $(document).ready(function() { lastRequest = _.toArray(arguments); }; - var a = new Backbone.Model({id: 3, label: 'a'}); - var b = new Backbone.Model({id: 2, label: 'b'}); - var c = new Backbone.Model({id: 1, label: 'c'}); - var d = new Backbone.Model({id: 0, label: 'd'}); - var e = null; - var col = window.col = new Backbone.Collection([a,b,c,d]); + var a = new Backbone.Model({id: 3, label: 'a'}); + var b = new Backbone.Model({id: 2, label: 'b'}); + var c = new Backbone.Model({id: 1, label: 'c'}); + var d = new Backbone.Model({id: 0, label: 'd'}); + var e = null; + var col = new Backbone.Collection([a,b,c,d]); + var otherCol = new Backbone.Collection(); test("Collection: new and sort", function() { equals(col.first(), a, "a should be first"); @@ -53,26 +54,34 @@ $(document).ready(function() { }); test("Collection: add", function() { - var added = opts = null; + var added = opts = secondAdded = null; + e = new Backbone.Model({id: 10, label : 'e'}); + otherCol.add(e); + otherCol.bind('add', function() { + secondAdded = true; + }); col.bind('add', function(model, collection, options){ added = model.get('label'); opts = options; }); - e = new Backbone.Model({id: 10, label : 'e'}); col.add(e, {amazing: true}); equals(added, 'e'); equals(col.length, 5); equals(col.last(), e); + equals(otherCol.length, 1); + equals(secondAdded, null); ok(opts.amazing); }); test("Collection: remove", function() { - var removed = null; + var removed = otherRemoved = null; col.bind('remove', function(model){ removed = model.get('label'); }); + otherCol.bind('remove', function(){ otherRemoved = true; }); col.remove(e); equals(removed, 'e'); equals(col.length, 4); equals(col.first(), d); + equals(otherRemoved, null); }); test("Collection: remove in multiple collections", function() {