【问题标题】:backbone.js cache collections and refreshBackbone.js 缓存集合和刷新
【发布时间】:2012-02-17 23:22:56
【问题描述】:

我有一个可能包含数千个模型的集合。我有一个视图,它显示一个表格,每页有 50 行。

现在我希望能够缓存我的数据,以便当用户加载表的第 1 页然后单击第 2 页时,第 1 页(行#01-50)的数据将被缓存,以便当用户再次点击第 1 页,主干无需再次获取它。

另外,我希望我的集合能够在不执行 RESET 的情况下从服务器刷新更新的数据,因为 RESET 将删除集合中的所有模型,包括我的应用程序中可能存在的现有模型的引用。是否可以通过比较现有数据和新到达的数据从服务器获取数据并仅在必要时更新或添加新模型?

【问题讨论】:

    标签: javascript caching collections backbone.js refresh


    【解决方案1】:

    Backbone.Collection.fetch 有一个选项 {add:true} 将模型添加到集合中而不是替换内容。

    myCollection.fetch({add:true})
    

    因此,在您的第一个场景中,来自 page2 的项目将被添加到集合中。

    就您的第二种情况而言,目前没有内置的方法可以做到这一点。

    According to Jeremy 这是您应该在您的应用程序中执行的操作,而不是 Backbone 的一部分。

    Backbone 在用于协作应用程序时似乎存在许多问题,其中另一个用户可能正在更新您拥有客户端的模型。我感觉 Jeremy 似乎专注于单用户应用程序,上面的票证讨论就是一个例子。

    在您的情况下,处理第二种情况的最简单方法是遍历您的集合并在每个模型上调用 fetch()。但是,这对性能来说不是很好。

    为了获得更好的方法,我认为您将不得不覆盖 collection._add,并按照 dalyons 在此 pull request 上所做的操作。

    【讨论】:

      【解决方案2】:

      在我的应用程序中,我通过添加一个名为 fetchNew 的新方法解决了重置问题:

      app.Collection = Backbone.Collection.extend({
      
          // fetch list without overwriting existing objects (copied from fetch())
          fetchNew: function(options) {
              options = options || {};
              var collection = this,
                  success = options.success;
              options.success = function(resp, status, xhr) {
                  _(collection.parse(resp, xhr)).each(function(item) {
                      // added this conditional block
                      if (!collection.get(item.id)) {
                          collection.add(item, {silent:true});
                      }
                  });
                  if (!options.silent) {
                      collection.trigger('reset', collection, options);
                  }
                  if (success) success(collection, resp);
              };
              return (this.sync || Backbone.sync).call(this, 'read', this, options);
          }
      
      });
      

      这与标准的fetch() 方法几乎相同,除了条件语句检查项目是否存在,并且默认使用add(),而不是reset。与简单地在 options 参数中传递 {add: true} 不同,它允许您检索可能与您已经加载的模型重叠的模型集 - 如果您尝试添加相同的模型两次,使用 {add: true} 将引发错误。

      这应该可以解决您的缓存问题,假设您的集合已设置为您可以在options 中传递某种page 参数来告诉服务器要发回哪个选项页面。您可能希望在您的集合中添加某种数据结构来跟踪您已加载的页面,以避免执行不必要的请求,例如:

      app.BigCollection = app.Collection.extend({
      
          initialize: function() {
              this.loadedPages = {};
          },
      
          loadPage: function(pageNumber) {
              if (!this.loadedPages[pageNumber]) {
                  this.fetchNew({ 
                      page: pageNumber,
                      success: function(collection) {
                          collection.loadedPages[pageNumber] = true;
                      }
                  })
              }
          }
      
      }); 
      

      【讨论】:

        【解决方案3】:

        我设法在 Backbone 0.9.9 核心中获得了 update。看看它,因为它正是你需要的 http://backbonejs.org/#Collection-update

        【讨论】:

        • 自 1.0.0 起,Collection#update 已重命名为 Collection#set
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-10
        • 2012-05-10
        • 1970-01-01
        • 1970-01-01
        • 2012-07-02
        相关资源
        最近更新 更多