2011-06-20 135 views
2

我刚开始使用backbone.js,我添加了一些基本方法来扩展一个集合,允许我遍历一个集合并保存所有模型,并遍历集合到销毁所有型号。我意识到批量更新不是RESTful,但我只是更新到本地存储,所以不认为这会是一个问题做多个更新。this.each不通过集合正确迭代

在我的基本应用程序中,该集合有9个模型。 当我调用collection.saveModels()时,它正确记录集合的长度,并正确保存所有模型。

当我调用collection.deleteModels()时,它正确地记录集合的长度,但会跳过每个第二个模型(即第2,4,6,8个)。每次按下删除键时,它将继续只删除奇怪的索引元素,最后一个要删除的项目是第8个原始项目。

是否有可能我错误地使用了每个功能,尽管保存时它可以正常工作?

_.extend(Backbone.Collection.prototype, Backbone.Events, { 
saveModels : function() { 
    console.log(this.length); 
    this.each(function(model){ 
     console.log('saving model ' + model.get('name')); 
     model.save(); 
    }); 
}, 
deleteModels : function() { 
    console.log(this.length); 
    this.each(function(model){ 
     console.log('deleting model ' + model.get('name')); 
     model.destroy(); 
    }); 
} 
}); 

,他们被称为像这样:mycollection.saveModels();mycollection.deleteModels();

我知道我可以通过基于长度集合迭代,但如果可能的话,我宁愿使用内置的方法。

+3

的主要问题,在一般情况下,在循环中删除的事情是,它搅乱了那里,循环目前是 - 环的长度被缩短,之后的“下一个”项指数实际上指的是项目下一个 - 例如,如果你删除第一个项目,循环的下一个索引将是第二个项目,但是第二个项目现在是第一个 - 所以第三个项目现在是第二个 - 希望是有意义的 – kinakuta

+0

啊,就是这样。甚至没有想过这个! – djlumley

+1

似乎你需要循环使用长度,但在任何情况下向后循环 – mplungjan

回答

8

代码bradgonesurfing贴不实际工作作为克隆方法不返回下划线的对象。正确的方法是使用_.chain方法使每个方法可链接。

_.chain(App.articles.models).clone().each(function(model){ 
    console.log('deleting model ' + model.get('name')); 
    model.destroy(); 
}); 
+0

绝对真棒!谢谢你! – nuc

5

每次调用model.destroy()时,它都会从集合中删除它自己。每个迭代器都不知道这一点。做下面的事情。

_.chain(App.articles.models).clone().each(function(model){ 
    console.log('deleting model ' + model.get('name')); 
    model.destroy(); 
}); 

主干可以访问underscore.js utils。首先克隆模型数组,然后 遍历它,然后销毁每个模型。应该可以工作

+1

您的解决方案无效,因为克隆不会返回下划线对象,我已经发布了使用链式方法的正确解决方案http://stackoverflow.com/a/11032971/109995 – JamieD

-1

这是我执行kinakuta's的评论我最后用的。下面

destroy_models : function() { 
    for (var i = this.length - 1; i > -1; i -=1){ 
     this.getByCid('c'+i).destroy(); 
    } 
} 
+0

这是完全错误的。您不能保证cid从0 ..(长度1)是连续的。看看getByCid的实现。它使用散列查找而不是数组索引查找。我上面的回答是正确的,并且可以在所有情况下工作。 – bradgonesurfing

+0

我做了一些更多的研究,看起来你是对的,我原本是做了upvote,但选择了我的答案,因为它提供了我的问题的答案〜 – djlumley

5

的代码为我工作很大:

destroyAll: function (options) { 
    while (this.models.length > 0) { 
     this.models[0].destroy(options); 
    }  
} 
+0

自从我用了一段时间以来骨干,但即将在另一个项目上使用它 - 这看起来像一个更好的解决方案 - 谢谢! – djlumley

+0

聪明!我一直在寻找解决方案。这是真棒 – Bingy