【问题标题】:Backbone: synchronizing Models and LocalStorageBackbone:同步模型和 LocalStorage
【发布时间】:2017-01-25 00:14:26
【问题描述】:

我已经扩展了一个模型A和一个集合如下:

define(['underscore', 'backbone', 'backbone.localStorage'], function(_, Backbone) {
   var A = Backbone.Model.extend({
      initialize: function() {          
      }
   });

   var A_Collection = Backbone.Collection.extend({
      model: A,
      localStorage: new Backbone.LocalStorage("as")
   });

   return {
      Model: A,
      Collection: A_Collection 
   };
});

集合存储在 localStorage 中,在我的应用程序中一切正常。然后我直接通过代码清除和替换localStorage(使用clear和setItem函数)并尝试实例化一个新的集合,但是没有检测到变化:

var aux = new A.Collection();
aux.fetch(); 
// aux is empty

否则如果尝试:

var aux = new A.Collection();
aux.localStorage = new Backbone.LocalStorage("as");
aux.fetch(); 
// aux contains new data 

后者对我无效,因为我必须修改项目中所有集合的创建。

我错过了什么?

【问题讨论】:

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


    【解决方案1】:

    Backbone.LocalStorage 的实例并非旨在侦听在其自身代码之外发生的LocalStorage 更改。这就是为什么你会得到你正在得到的行为。但是,有一种解决方法。

    当你像这样定义一个集合时:

    var A_Collection = Backbone.Collection.extend({
       model: A,
       localStorage: new Backbone.LocalStorage("as")
    });
    

    localStorage 值由A_Collection 的所有实例共享。您可以自动创建Backbone.LocalStorage 的新实例,如下所示:

    var A_Collection = Backbone.Collection.extend({
      model: A,
      initialize: function() {
        A_Collection.__super__.initialize.apply(this, arguments);
        A_Collection.prototype.localStorage = new Backbone.LocalStorage("as");
      },
    });
    

    我们必须在原型上设置它,以便A_Collection 的所有实例共享它,这与原始代码的行为相同。有了这个,每当你创建一个A_Collection 的新实例时,你都会得到一个Backbone.LocalStorage 的新实例,它将从LocalStorage 重新获取信息。

    这是一个plunker 的说明。以下是相关代码,供参考:

    var A = Backbone.Model.extend({
      initialize: function() {}
    });
    
    var A_Collection = Backbone.Collection.extend({
      model: A,
      initialize: function() {
        A_Collection.__super__.initialize.apply(this, arguments);
        A_Collection.prototype.localStorage = new Backbone.LocalStorage("as");
      },
    });
    
    // Setup a collection.
    var collection = new A_Collection();
    collection.fetch();
    
    // Clean it out from previous runs... Note that we have to use destroy to destroy all items. 
    // Reset won't save to LocalStorage.
    while (collection.length > 0) {
      var model = collection.at(0);
      model.destroy();
      collection.remove(model);
    }
    // and set some elements.
    collection.create({
      name: "1"
    });
    collection.create({
      name: "2"
    });
    console.log("collection length:", collection.length);
    
    // Mess with it outside the Backbone code.
    localStorage.clear();
    // Manually create data that looks like what Backbone expects.
    localStorage.setItem("as-1", JSON.stringify({
      name: "foo",
      id: "1"
    }));
    localStorage.setItem("as-2", JSON.stringify({
      name: "bar",
      id: "2"
    }));
    localStorage.setItem("as-3", JSON.stringify({
      name: "baz",
      id: "3"
    }));
    localStorage.setItem("as", "1,2,3");
    
    // Create a new collection that loads from LocalStorage
    var collection2 = new A_Collection();
    collection2.fetch();
    console.log("collection 2 length:", collection2.length);
    console.log("first item", collection2.at(0).toJSON());
    console.log("third item", collection2.at(2).toJSON());
    
    console.log("instance is shared?", collection.localStorage === collection2.localStorage);
    

    上面的代码在控制台上生成:

    collection length: 2
    collection 2 length: 3
    first item Object {name: "foo", id: "1"}
    third item Object {name: "baz", id: "3"}
    instance is shared? true
    

    【讨论】:

    • 哇,印象深刻。这就是我一直在寻找的。非常感谢
    猜你喜欢
    • 1970-01-01
    • 2016-05-30
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多