backbone.js – 将主干集合与服务器响应合并

前端之家收集整理的这篇文章主要介绍了backbone.js – 将主干集合与服务器响应合并前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
TL; DR:如果我从服务器轮询整个模型集合,如何将更改的属性合并到每个模型中,并从集合中添加/删除添加/删除的模型?

在我的骨干应用程序中,我正在轮询整个模型集合.我有一个Backbone.Collection,我每次获得模型数组时基本上都会调用reset,所以:

  1. myCollection.reset(server_response);

唯一的问题是它摆脱了旧模型,消除了模型上事件的好处.这当然是重置的目的,但我想要做的只是修改模型的更改属性,删除不在响应中的模型,并添加响应中但不是集合的模型.

基本上我想要一种数据合并.

对于已经在响应中和集合中的模型,我相信我可以只进行model.set(属性),它只负责设置实际更改的模型,触发流程中的更改事件.这很棒.

但是,我如何处理模型在响应中但不在集合中的情况,反之亦然,不是在响应中而是在集合中?

我建议的解决方

我不知道骨干是否已经有办法做到这一点,我可能会过度复杂,这就是为什么我要问,但我当时正在考虑在我的集合上创建一个方法来传递server_response.

它将获取server_response的所有id属性,以及集合中已存在的模型的所有id属性.

响应中的id的差异 – 收集将=添加模型,反之亦然将被移除模型.分别从集合中添加删除这些模型.

两组id的交集将是修改后的模型,因此迭代这些id并简单地执行collection.get(id).set(attributes).

在pseudocoffeescript中:

  1. merge: (server_response) =>
  2. response_ids = _.pluck(server_response,'id')
  3. collection_ids = @pluck('id')
  4.  
  5. added = _.difference(response_ids,collection_ids)
  6.  
  7. for add in added
  8. @add(_.find(server_response,(model) ->
  9. return model.id == add
  10. ))
  11.  
  12. removed = _.difference(collection_ids,response_ids)
  13.  
  14. for remove in removed
  15. @remove(@get(remove))
  16.  
  17. changed = _.intersection(response_ids,collection_ids)
  18.  
  19. for change in changed
  20. @get(change).set(_.find(server_response,(model) ->
  21. return model.id == change
  22. ))

解决方法

这种技术有时很有用.我们使用以下方法扩展Collection.这应该做你想要的.它不是咖啡,但你可以轻松移植它.请享用!
  1. // Take an array of raw objects
  2. // If the ID matches a model in the collection,set that model
  3. // If the ID is not found in the collection,add it
  4. // If a model in the collection is no longer available,remove it
  5. freshen: function (objects) {
  6. var model;
  7. // Mark all for removal
  8.  
  9. this.each(function (m) {
  10. m._remove = true;
  11. });
  12.  
  13. // Apply each object
  14. _(objects).each(function (attrs) {
  15. model = this.get(attrs.id);
  16. if (model) {
  17. model.set(attrs); // existing model
  18. delete model._remove
  19. } else {
  20. this.add(attrs); // new model
  21. }
  22. },this);
  23.  
  24. // Now check for any that are still marked for removal
  25. var toRemove = this.filter(function (m) {
  26. return m._remove;
  27. })
  28.  
  29. _(toRemove).each(function (m) {
  30. this.remove(m);
  31. },this);
  32. this.trigger('freshen',this);
  33. }

猜你在找的JavaScript相关文章