Skip to content

Instantly share code, notes, and snippets.

@mattheworiordan
Created June 21, 2011 14:35
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save mattheworiordan/1037984 to your computer and use it in GitHub Desktop.
Save mattheworiordan/1037984 to your computer and use it in GitHub Desktop.
Backbone patch to defer update method requests when new create requests are not complete on a model
(function() {
Backbone.Model.prototype._save = Backbone.Model.prototype.save;
Backbone.Model.prototype.save = function(attrs, options) {
var that = this;
if (!options) { options = {}; }
if (this.savingNewRecord) {
// store or replace last PUT request with the latest version, we can safely replace old PUT requests with new ones
// but if there are callbacks from a previous PUT request, we need to make sure they are all called as well
_(['success','error']).each(function(event) {
// convert all callbacks to a single array of callbacks)
var existingCallbacks = that.putQueue ? that.putQueue.options[event] : [];
options[event] = _.compact( existingCallbacks.concat(options[event]) );
});
this.putQueue = { attributes: _.extend({}, that.attributes, attrs), options: options };
} else {
if (this.isNew()) {
// saving a new record so we need to wait for server to respond and assign an ID before the model is saved again
this.savingNewRecord = true;
// store the old callback and overwrite so we can catch the success/error event when savint this model
_(['success','error']).each(function(event) {
var oldEventCallback = options[event];
options[event] = function(model, response) {
that.savingNewRecord = false;
// check if callback for this model save exists and if so execute the callback
if (oldEventCallback) { oldEventCallback.apply(this, model, response); }
// if there is a PUT waiting to fire, fire it now
if (that.putQueue) {
// as PUT builds up callbacks as arrays, lets create a callback which executes all the callbacks
_(['success','error']).each(function(callBackEvent) {
var callbacks = _.clone(that.putQueue.options[callBackEvent]);
that.putQueue.options[callBackEvent] = function(model, response) {
var callbackThis = this;
_(callbacks).each(function(callback) {
callback.apply(callbackThis, model, response);
})
};
});
Backbone.Model.prototype.save.call(that, _.extend({}, that.attributes, that.putQueue.attributes), that.putQueue.options);
}
};
});
}
Backbone.Model.prototype._save.call(this, attrs, options);
}
};
}());
@philfreo
Copy link

I tried your latest version again after some other cleanup in my app, and I get this:
http://cl.ly/image/2E1P1V3O2V38

@philfreo
Copy link

(which includes some parallel requests -- and also it's queuing up way too many still - later ones don't seem to be canceling earlier ones)

@rinatio
Copy link

rinatio commented Oct 11, 2012

If i use this code $.when(model.save()).done(callback) doesn't work.

@rinatio
Copy link

rinatio commented Oct 11, 2012

And evens don't work: model.on('success', callback)

@rinatio
Copy link

rinatio commented Oct 11, 2012

Here is possible fix, but i'm not sure about events triggering: https://gist.github.com/3873386

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment