Backbone.js解析未修改的响应

Ant*_*rev 5 javascript etag jquery caching backbone.js

我有一个使用标题ETag的服务器.Backbone首次引用API:一切都很好,收到的响应和解析.第二次:骨干发送到服务器ETag,作为响应接收NotModified.而Backbone试图解析这个响应,导致一个名为reset的集合.

有什么方法可以重置收藏吗?

在fetch方法中添加要添加的选项的方法将不起作用.因为我需要完全刷新集合,如果我来到服务器的响应.

var recommendCollection = Backbone.Collection.extend({
    model : Event,
    etag : null,
    urlRoot : '/api/users',
    initialize: function() {
        this.etag = null;
    },
    parse: function(response) {
        return response.data;
    },      
    url : function () {
        return (this.urlRoot + "/"+window.me.get('id')+ "/recommendation");
    },
    beforeSend : function (jqXHR, settings) {
        jqXHR.setRequestHeader('if-none-match', this.etag);
    },
    complete : function (jqXHR, textStatus) {
        if (jqXHR.status == 200 || jqXHR.status == 304) {
            this.etag = jqXHR.getResponseHeader('ETag');
        }
    },
    update : function () {
        this.fetch({
            beforeSend : this.beforeSend.bind(this),
            complete : this.complete.bind(this),
            data : {
                cityId : window.me.get('cityId'),
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

nik*_*shr 8

据我所知,没有简单的解决方案来捕获304响应.我想出了什么:

  • parse接收第二个参数,options即你可以用它来检查请求的状态,并在必要时以相同的模式重新填充您的收藏.它有效,但它会触发一个reset

    parse: function(response, options) {
        if (options.xhr.status === 304)
            return this.models
    
        return response.data;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    http://jsfiddle.net/nikoshr/sxv9P/12/

  • jQuery接受一个ifModified可以帮助你的选项

    ifModified 默认值:false

    仅在自上次请求后响应已更改时才允许请求成功.这是通过检查Last-Modified标头来完成的.默认值为false,忽略标头.在jQuery 1.4中,这种技术还检查服务器指定的'etag'以捕获未修改的数据.

  • 或覆盖fetch函数以停止304响应

    fetch: function(options) {
          options = options ? _.clone(options) : {};
          if (options.parse === undefined) options.parse = true;
          var collection = this;
          var success = options.success;
          options.success = function(resp, status, xhr) {
            if (xhr.status!==304)
                collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
            if (success) success(collection, resp);
          };
          options.error = Backbone.wrapError(options.error, collection, options);
          return (this.sync || Backbone.sync).call(this, 'read', this, options);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    http://jsfiddle.net/sxv9P/1/