将主干集合与服务器响应合并
TL;DR:如果我从服务器轮询整个模型集合,如何将更改的属性合并到每个模型中,并从集合中添加/删除添加/删除的模型?
在我的主干应用程序中,我正在轮询整个模型集合。我有一个 Backbone.Collection
,每次获取模型数组时我基本上都会调用 reset
,所以:
myCollection.reset(server_response);
唯一的问题是它摆脱了旧模型,有点消除了事件对模型的好处。这当然是reset
的目的,但我想做的只是修改模型的更改属性,并删除不在响应中的模型,并添加在响应中但不在响应中的模型集合。
本质上,我想要对数据进行某种合并。
对于已经在响应和集合中的模型,我相信我可以执行 model.set(attributes) ,并且它只负责设置
那些实际上发生了变化,触发了流程中的 change
事件。这太棒了。
但是,如何处理模型在响应中但不在集合中的情况,反之亦然,不在响应中但在集合中?
我提出的解决方案
我不知道骨干是否已经有办法做到这一点,我可能过于复杂,这就是我问的原因,但我当时正在考虑在我的集合上创建一种方法它通过server_response
。
它将获取 server_response
的所有 id
属性,以及集合中已有模型的所有 id
属性。
响应中 id
的差异 - 集合 = 添加模型,反之亦然将删除模型。分别从集合中添加和删除这些模型。
两组 id
的交集将是修改后的模型,因此迭代这些 id
并简单地执行 collection.get(id)。设置(属性)
。
在伪咖啡脚本中:
merge: (server_response) =>
response_ids = _.pluck(server_response, 'id')
collection_ids = @pluck('id')
added = _.difference(response_ids, collection_ids)
for add in added
@add(_.find(server_response, (model) ->
return model.id == add
))
removed = _.difference(collection_ids, response_ids)
for remove in removed
@remove(@get(remove))
changed = _.intersection(response_ids, collection_ids)
for change in changed
@get(change).set(_.find(server_response, (model) ->
return model.id == change
))
TL;DR: If I'm polling the entire collection of models from the server, how can I merge the changed attributes into each model and add/remove added/removed models from the collection?
In my backbone app, I am polling for the entire collection of models. I have a Backbone.Collection
that I am basically calling reset
on each time I get the array of models, so:
myCollection.reset(server_response);
The only problem with this is that it gets rid of the old models, kind of eliminating the benefit of events on a model. This is reset
's purpose of course, but what I want to do is only modify the changed attributes of the models, and remove models not in the response, and add models that were in the response but not the collection.
Essentially I want a sort of merge of the data.
For models that are in the response and in the collection already, I believe I can just do model.set(attributes)
and it takes care of set
ing only the ones that actually changed, triggering the change
events in the process. This is great.
But how do I handle the cases where the models were in the response but not in the collection already, and vice versa, not in the response but in the collection?
My Proposed Solution
I don't know if backbone already has a way of doing this, and I may be overcomplicating which is why I'm asking, but I was thinking then of creating a method on my collection which gets passed the server_response
.
It would get all of the id
attributes of the server_response
, and all of the id
attributes of the models already in the collection.
The difference of the id
's in response - collection would = added models, and vice versa would be removed models. Add and remove those models respectively from the collection.
The intersection of both sets of id
's would be the modified models, so iterate through these id
's and simply do a collection.get(id).set(attributes)
.
In pseudocoffeescript:
merge: (server_response) =>
response_ids = _.pluck(server_response, 'id')
collection_ids = @pluck('id')
added = _.difference(response_ids, collection_ids)
for add in added
@add(_.find(server_response, (model) ->
return model.id == add
))
removed = _.difference(collection_ids, response_ids)
for remove in removed
@remove(@get(remove))
changed = _.intersection(response_ids, collection_ids)
for change in changed
@get(change).set(_.find(server_response, (model) ->
return model.id == change
))
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这种技术有时很有用。我们使用以下方法扩展 Collection。这应该可以满足您的要求。它不在咖啡中,但您可以轻松移植它。享受!
This technique is useful sometimes. We extend Collection with the following method. This should do what you're looking for. It's not in coffee, but you could easily port it. Enjoy!
这三天前刚刚进入 Backbone master:
https://github.com/documentcloud/backbone/pull/1220
This just went into Backbone master 3 days ago:
https://github.com/documentcloud/backbone/pull/1220