Javascript 如何有选择地从主干集合和服务器中删除模型?

Javascript 如何有选择地从主干集合和服务器中删除模型?,javascript,backbone.js,Javascript,Backbone.js,例如,如果要从待办事项列表中删除已完成的待办事项 有选择地从主干网集合和服务器中删除模型似乎是一项常见的任务。常见的方法是什么?每种方法的成本和收益是什么?解决方案一 var toRemove = collection.filter(function(model) { return condition(model); }); _.invoke(toRemove, 'destroy'); var toRemove = []; collection.forEach(function(model

例如,如果要从待办事项列表中删除已完成的待办事项


有选择地从主干网集合和服务器中删除模型似乎是一项常见的任务。常见的方法是什么?每种方法的成本和收益是什么?

解决方案一

var toRemove = collection.filter(function(model) {
  return condition(model);
});
_.invoke(toRemove, 'destroy');
var toRemove = [];
collection.forEach(function(model) {
  if (condition(model)) toRemove.push(model);
});
toRemove.forEach(function(model) {
  model.destroy();
});
这似乎是最干净的方式。这就是Addy在他的书中删除已完成的TODO(这也是我首先列出此解决方案的一个重要原因)。如果你重复使用filter函数(就像他那样),它会特别干净

然而,我认为它比解决方案二慢,因为它涉及对
集合
移动
的迭代,而解决方案二只涉及对
集合
的迭代。尽管如此,它们都有线性运行时间,所以这没什么大不了的


解决方案二

for (var i = collection.models.length-1; i >= 0; i--) { // looping from back to front
  var model = collection.models[i];
  if (condition(model)) model.destroy();
}
我觉得这个比较干净。如上所述,这样做的好处是只需在集合中循环,而不是集合+集合的过滤版本

从后到前循环是很重要的。考虑从前后循环时发生的事情:

for (var i = 0; i < collection.models.length; i++) { // looping from front to back
  var model = this.models[i];
  if (condition(model)) {
    model.destroy();
    i--;
  }
}
这与解决方案1非常相似

差异:

  • 我们正在使用一个
    forEach
    来构造
    toRemove
    ,而不是
    filter

  • 我们正在手动迭代并调用
    destroy
    ,而不是使用
    invoke

  • 与解决方案一类似,您必须通过
    集合
    进行迭代才能移动
    ,因此所需时间可能比解决方案二长

    注意:我们不能在第一个
    forEach
    循环中销毁模型。如果我们这样做,那么它的问题与解决方案2中的前后循环相同。为了绕过这个限制,我们必须使用
    来移动
    数组


    解决方案四

    这将使用
    reset()
    +事件
    reset

    var toKeep = collection.filter(function(model) {
      return condition(model);
    });
    collection.reset(toKeep);
    


    这对我来说似乎有点过分,但却是一种选择。

    我认为在
    reset()
    set()
    之后调用
    sync()
    是没有办法的。
    我想
    sync()
    只支持
    read
    收藏<代码>第二个参数model是主干。model或主干。Collection–在读取多个值时使用集合。
    -。如果是这样,要使用
    sync()
    ,您必须自定义它来完成我在回答中讨论的事情。我只是快速查看了源代码,它看起来像是,但我没有时间测试它,因此作为注释发布:)
    collection.on('reset', function(after, before) {
      // let after.length = k
      // let before.length = n
      after.sort(); // k*logk
      for (var i = before.length-1; i >= 0; i--) { // n
        var model = before[i];
        if (!binarySearch(model, after)) model.remove(); // logk
      }
      // total runtime: n*logk + k*logk
    });