Backbone:正在同步模型和本地存储
Backbone: synchronizing Models and LocalStorage
我扩展了模型 A 和 As 的集合,如下所示:
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
后者对我无效,因为我必须修改项目中所有集合的创建。
我错过了什么?
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
我扩展了模型 A 和 As 的集合,如下所示:
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
后者对我无效,因为我必须修改项目中所有集合的创建。
我错过了什么?
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