我可以使用jQuery的deferred.pipe方法来修改提供给已解决/失败回调的参数吗?



我希望能够使用jQuery的延期对象通过骨干集合和型号操作加载数据。有什么方法可以修改提供给完成的参数并失败回调以包括模型或集合实例?我正在设想以下内容:

var _sync = Backbone.sync;
Backbone.sync = function() {
    var jqXhr = _sync.apply(this, arguments);
    var self = this;
    return jqXhr.pipe(function() {
        var cbArgs = [self];
        cbArgs.push.apply(cbArgs, arguments);
        return cbArgs; 
    }
}
...
var c = new Backbone.Collection();
c.url = "/path/to/resources";
c.fetch().then(function(collection, data, textStatus, jqXhr) {
    // do stuff with collection
});

当然,由于过滤器正在返回数组,因此完成的回调是用数组调用的,而不是枚举的参数。据我所知,管道只能修改提供的参数,而不是添加。任何建议都将不胜感激。

编辑:这是一个非常简单的示例;由于在原始集合上创建了关闭,因此我可以对此进行操作。但是,用例是多个骨干视图可能依赖于所获取的相同数据,因此我希望能够仅向这些视图提供jQuery递延对象,而不是递延和集合实例。

另一个编辑:在下面发布了一个解决方案,但欢迎任何其他建议。

我发现我可以通过让.pipe方法返回一个新的$ .deferred来实现这一目标,该$ .deferred使用修改后的参数立即解决:

var _sync = Backbone.sync;
Backbone.sync = function() {
    var jqXhr = _sync.apply(this, arguments);
    var self = this;
    var deferred = jqXhr.pipe(function() {
        var cbArgs = [self];
        cbArgs.push.apply(cbArgs, arguments);
        var deferred = new $.Deferred();
        return deferred.resolve.apply(deferred, cbArgs);
    });
    return $.extend(true, jqXhr, deferred);
};

一个与您的答案非常相似的解决方案,但是没有管道,因为您实际上不需要过滤结果:我直接返回了从backbone.sync返回新的推迟而不是管道解决方案递延

Backbone.originalSync = Backbone.sync;
Backbone.sync = function(method, model, options) {
    var xhr = Backbone.originalSync.call(this, method, model, options);
    var dfd = $.Deferred();
    xhr.done(function() {
        var cbArgs = [model].concat(_.toArray(arguments));
        dfd.resolve.apply(dfd, cbArgs);
    });
    xhr.fail(function() {
        var cbArgs = [model].concat(_.toArray(arguments));
        dfd.reject.apply(dfd, cbArgs);
    });
    return dfd;
};

和小提琴http://jsfiddle.net/d8fqa/

如果您愿意将this绑定到回调中的型号/集合,则更简单的变化,这使函数签名未触及:

Backbone.originalSync = Backbone.sync;
Backbone.sync = function(method, model, options) {
    var xhr = Backbone.originalSync.call(this, method, model, options);
    var dfd = $.Deferred();
    xhr.done(function() {
        dfd.resolveWith(model, arguments);
    });
    xhr.fail(function() {
        dfd.rejectWith(model, arguments);
    });
    return dfd;
};
var c=new Backbone.Collection();
c.fetch().done(function() {
    console.log(this);
    console.log(arguments);
});

http://jsfiddle.net/d8fqa/1/

导致我们将模型作为上下文传递给Ajax请求:

Backbone.originalSync = Backbone.sync;
Backbone.sync = function(method, model, options) {
    options || (options={}) ;
    options.context = model;
    return Backbone.originalSync.call(this, method, model, options);
};
var c=new Backbone.Collection();
c.fetch().done(function() {
    console.log(this);
});

http://jsfiddle.net/d8fqa/2/

最新更新