diff --git a/backbone.js b/backbone.js index 7e713ecd..2bdba4eb 100644 --- a/backbone.js +++ b/backbone.js @@ -705,6 +705,7 @@ var toAdd = [], toRemove = [], modelMap = {}; var add = options.add, merge = options.merge, remove = options.remove; var order = !sortable && add && remove ? [] : false; + var orderChanged = false; // Turn bare objects into model references, and prevent invalid models // from being added. @@ -735,7 +736,12 @@ model = existing || model; if (!model) continue; id = this.modelId(model.attributes); - if (order && (model.isNew() || !modelMap[id])) order.push(model); + if (order && (model.isNew() || !modelMap[id])) { + order.push(model); + // Check to see if this is actually a new model at this index. + orderChanged = orderChanged || !this.models[i] || model.cid !== this.models[i].cid; + } + modelMap[id] = true; } @@ -748,7 +754,7 @@ } // See if sorting is needed, update `length` and splice in new models. - if (toAdd.length || (order && order.length)) { + if (toAdd.length || (orderChanged && order && order.length)) { if (sortable) sort = true; this.length += toAdd.length; if (at != null) { @@ -774,7 +780,7 @@ if (at != null) addOpts.index = at + i; (model = toAdd[i]).trigger('add', model, this, addOpts); } - if (sort || (order && order.length)) this.trigger('sort', this, options); + if (sort || orderChanged) this.trigger('sort', this, options); } // Return the added (or merged) model (or models). diff --git a/test/collection.js b/test/collection.js index c45c106b..08659fed 100644 --- a/test/collection.js +++ b/test/collection.js @@ -1454,4 +1454,26 @@ col.add([{at: 1}, {at: 2}]); }); + test('#3199 - Order changing should trigger a sort', 1, function() { + var one = new Backbone.Model({id: 1}); + var two = new Backbone.Model({id: 2}); + var three = new Backbone.Model({id: 3}); + var collection = new Backbone.Collection([one, two, three]); + collection.on('sort', function() { + ok(true); + }); + collection.set([{id: 3}, {id: 2}, {id: 1}]); + }); + + test('#3199 - Order not changing should not trigger a sort', 0, function() { + var one = new Backbone.Model({id: 1}); + var two = new Backbone.Model({id: 2}); + var three = new Backbone.Model({id: 3}); + var collection = new Backbone.Collection([one, two, three]); + collection.on('sort', function() { + ok(false); + }); + collection.set([{id: 1}, {id: 2}, {id: 3}]); + }); + })();