一个Backbone集合中的LocalStorage和URL

时间:2016-11-25 21:15:02

标签: javascript backbone.js backbone-local-storage

我有一个集合,从URL中提取数据。

BarCollection = Backbone.Collection.extend({
  model: BarModel,
  url: // Some URL
});

但问题是我想要不仅从URL获取数据到此集合,还要从本地存储获取数据。我希望我能做那样的事情:

BarCollection = Backbone.Collection.extend({
  model: BarModel,
  url: // Some URL,
  localStorage: new Backbone.LocalStorage('bars')
});

.fetch()方法无法从网址和本地存储中获取数据。

简单的解决方法是创建两个不同的集合:一个用于URL,另一个用于本地存储。取出后只需合并它们。

BarCollection = Backbone.Collection.extend({
  model: BarModel,
  url: // Some URL
});

LocalBarCollection = Backbone.Collection.extend({
  model: BarModel,
  localStorage: new Backbone.LocalStorage('local-contributors')
});

我想知道是否有更美妙的方式。

1 个答案:

答案 0 :(得分:0)

要使任何集合或模型能够同时从localStorage和服务器同步,可以覆盖Backbone的同步功能:

Backbone.sync = (function(sync) {
    return function(method, model, options) {
        options = options || {};
        var key = _.result(model, 'localStorage'),
            response;

        // if the localStorage property exist on the model/collection
        // first try to sync with the localStorage
        if (key) {
            switch (method) {
                case 'create':
                case 'update':
                    var data = model.toJSON(),
                        text = JSON.stringify(data);
                    localStorage.setItem(key, text);
                    break;
                case 'delete':
                    localStorage.removeItem(key);
                    break;
                case 'read':
                    response = JSON.parse(localStorage.getItem(key));
                    if (response) model.set(response, { parse: true });
                    break;
            }
        }

        // then, always sync with the server as it normally would
        return sync.apply(this, arguments);
    };
})(Backbone.sync);

这样,如果模型或集合作为localStorage属性,它将首先与localStorage同步,然后它将进行原始同步。

示例模型和集合:

var BarModel = Backbone.Model.extend({
    urlRoot: 'some/url',
    localStorage: function() {
        return 'bars-' + this.id;
    },
});

var BarCollection = Backbone.Collection.extend({
    model: BarModel,
    url: '/some/url',
    localStorage: 'bars',
});