diff --git a/backbone.js b/backbone.js index 16bd9661..51f0f2cb 100644 --- a/backbone.js +++ b/backbone.js @@ -343,7 +343,7 @@ // If the server returns an attributes hash that differs, the model's // state will be `set` again. save: function(key, value, options) { - var attrs, current; + var attrs, current, done; // Handle both `("key", value)` and `({key: value})` -style calls. if (_.isObject(key) || key == null) { @@ -375,11 +375,9 @@ var model = this; var success = options.success; options.success = function(resp, status, xhr) { + done = true; var serverAttrs = model.parse(resp, xhr); - if (options.wait) { - delete options.wait; - serverAttrs = _.extend(attrs || {}, serverAttrs); - } + if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs); if (!model.set(serverAttrs, options)) return false; if (success) success(model, resp, options); model.trigger('sync', model, resp, options); @@ -388,7 +386,14 @@ // Finish configuring and sending the Ajax request. options.error = Backbone.wrapError(options.error, model, options); var xhr = this.sync(this.isNew() ? 'create' : 'update', this, options); - if (options.wait) this.clear(silentOptions).set(current, silentOptions); + + // When using `wait`, reset attributes to original values unless + // `success` has been called already. + if (!done && options.wait) { + this.clear(silentOptions); + this.set(current, silentOptions); + } + return xhr; }, diff --git a/test/collection.js b/test/collection.js index 776fc33b..a6f5bae9 100644 --- a/test/collection.js +++ b/test/collection.js @@ -648,4 +648,12 @@ $(document).ready(function() { collection.fetch(); collection.create({id: 1}); }); + + test("#1447 - create with wait adds model.", function() { + var collection = new Backbone.Collection; + var model = new Backbone.Model; + model.sync = function(method, model, options){ options.success(); }; + collection.on('add', function(){ ok(true); }); + collection.create(model, {wait: true}); + }); }); diff --git a/test/model.js b/test/model.js index 62661dff..8689d975 100644 --- a/test/model.js +++ b/test/model.js @@ -632,16 +632,14 @@ $(document).ready(function() { equal(model.get('x'), void 0); }); - test("`save` with `wait` results in correct attributes if success is called during sync", 2, function() { - var changed = 0; + test("#1030 - `save` with `wait` results in correct attributes if success is called during sync", 2, function() { var model = new Backbone.Model({x: 1, y: 2}); model.sync = function(method, model, options) { options.success(); }; - model.on("change:x", function() { changed++; }); + model.on("change:x", function() { ok(true); }); model.save({x: 3}, {wait: true}); equal(model.get('x'), 3); - equal(changed, 1); }); test("save with wait validates attributes", 1, function() {