backbone.js缓存集合和刷新

时间:2012-01-24 17:42:45

标签: javascript caching collections backbone.js refresh

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

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

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

3 个答案:

答案 0 :(得分:6)

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

myCollection.fetch({add:true})

因此,在您的第一个场景中,第2页中的项目将添加到集合中。

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

According to Jeremy这是您在应用中应该做的事情,而不是Backbone的一部分。

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

在您的情况下,处理第二种方案的最简单方法是迭代您的集合并在每个模型上调用fetch()。但是,这对于表现并不是很好。

为了更好的方法,我认为您将不得不覆盖collection._add,并在此pull request上执行dalyons行。

答案 1 :(得分:6)

在我的应用中,我通过添加名为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。与简单地在{add: true}参数中传递options不同,它允许您检索可能与已加载的模型重叠的模型集 - 如果您尝试添加{add: true}将导致错误相同的模型两次。

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

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;
                }
            })
        }
    }

}); 

答案 2 :(得分:1)

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