diff --git a/backbone.js b/backbone.js index fd044cd7..03006acc 100644 --- a/backbone.js +++ b/backbone.js @@ -251,7 +251,7 @@ this.attributes = {}; if (options.collection) this.collection = options.collection; if (options.parse) attrs = this.parse(attrs, options) || {}; - options._attrs = attrs; + options._attrs || (options._attrs = attrs); if (defaults = _.result(this, 'defaults')) { attrs = _.defaults({}, attrs, defaults); } @@ -685,6 +685,7 @@ if (remove) modelMap[existing.cid] = true; if (merge) { attrs = attrs === model ? model.attributes : options._attrs; + delete options._attrs; existing.set(attrs, options); if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true; } diff --git a/test/collection.js b/test/collection.js index 915579fd..f35d67fe 100644 --- a/test/collection.js +++ b/test/collection.js @@ -967,6 +967,22 @@ $(document).ready(function() { equal(col.length, 1); }); + test('merge without mutation', function () { + var Model = Backbone.Model.extend({ + initialize: function (attrs, options) { + if (attrs.child) { + this.set('child', new Model(attrs.child, options), options); + } + } + }); + var Collection = Backbone.Collection.extend({model: Model}); + var data = [{id: 1, child: {id: 2}}]; + var collection = new Collection(data); + equal(collection.first().id, 1); + collection.set(data); + equal(collection.first().id, 1); + }); + test("`set` and model level `parse`", function() { var Model = Backbone.Model.extend({ parse: function (res) { return res.model; }