我能够覆盖对 ajax 请求进行排队的 collection.create。为此,我使用了此答案中的代码。
var Documents = Backbone.Collection.extend({
model: Document,
url: "/a/documents",
initialize: function() {
this.on("add remove", this.updatePositions, this);
this.ajaxQueue = $({});
},
updatePositions: function(model, collection, options) {
this.each(function(m, index) {
m.set({position: index + 1});
})
},
create: function(model, options) {
var jqXHR
, dfd = $.Deferred()
, promise = dfd.promise()
, coll = this;
// queue our ajax request
this.ajaxQueue.queue(doRequest);
// add the abort method
promise.abort = function(statusText) {
// Proxy abort to the jqXHR if it is active
if (jqXHR) {
return jqXHR.abort(statusText);
}
// If there wasn't already a jqXHR we need to remove from queue
var queue = this.ajaxQueue.queue()
, index = $.inArray(doRequest, queue);
if (index > -1) {
queue.splice(index, 1);
}
// Reject the deferred
dfd.rejectWith(options.context || options,
[promise, statusText, ""]);
return promise;
};
// Run the actual collection.create
function doRequest(next) {
options = options ? _.clone(options) : {};
model = coll._prepareModel(model, options);
if (!model) return false;
if (!options.wait) coll.add(model, options);
var success = options.success;
options.success = function(nextModel, resp, xhr) {
if (options.wait) coll.add(nextModel, options);
if (success) {
success(nextModel, resp);
} else {
nextModel.trigger('sync', model, resp, options);
}
};
jqXHR = model.save(null, options)
.done(dfd.resolve)
.fail(dfd.reject)
.then(next, next);
};
return promise;
}
});