TL; DR :如果我从服务器轮询整个模型集合,如何将更改的属性合并到每个模型中,并从集合中添加/删除添加/删除的模型?
在我的骨干应用程序中,我正在轮询整个模型集合。我有一个Backbone.Collection
,每次我得到模型数组时,我基本上都会调用reset
,所以:
myCollection.reset(server_response);
唯一的问题是它摆脱了旧模型,消除了模型上事件的好处。这当然是reset
的目的,但我想要做的只是修改模型的已更改属性,并删除不在响应中的模型,并添加响应中但不是集合的模型。
基本上我想要一种合并的数据。
对于已经在响应中和集合中的模型,我相信我可以做model.set(attributes)
并且只处理set
仅实际更改的模型,触发{{1}进程中的事件。这很棒。
但是我如何处理模型在响应中但不在集合中的情况,反之亦然,不是在响应中而是在集合中?
我建议的解决方案
我不知道骨干是否已经有办法做到这一点,我可能会过度复杂,这就是为什么我要问,但我当时正在考虑在我的集合上创建一个方法,它传递给{{1 }}
它将获取change
的所有server_response
属性,以及集合中已有的所有id
属性。
响应中server_response
的差异 - 收集将=添加模型,反之亦然将被移除模型。分别从集合中添加和删除这些模型。
两组id
的交集将是修改后的模型,因此请遍历这些id
并简单地执行id
。
在pseudocoffeescript中:
id
答案 0 :(得分:9)
这种技术有时很有用。我们使用以下方法扩展Collection。这应该做你想要的。它不是咖啡,但你可以轻松移植它。享受!
// Take an array of raw objects
// If the ID matches a model in the collection, set that model
// If the ID is not found in the collection, add it
// If a model in the collection is no longer available, remove it
freshen: function (objects) {
var model;
// Mark all for removal
this.each(function (m) {
m._remove = true;
});
// Apply each object
_(objects).each(function (attrs) {
model = this.get(attrs.id);
if (model) {
model.set(attrs); // existing model
delete model._remove
} else {
this.add(attrs); // new model
}
}, this);
// Now check for any that are still marked for removal
var toRemove = this.filter(function (m) {
return m._remove;
})
_(toRemove).each(function (m) {
this.remove(m);
}, this);
this.trigger('freshen', this);
}
答案 1 :(得分:4)
3天前刚刚进入Backbone master: