这个应该很简单,但事实并非如此,这让我很头疼。
我复制/粘贴了一个相当简单的“Hello Backbone”代码,并对其进行了简化,以获得此代码:
(function($){
var Item = Backbone.Model.extend({
defaults: {
part1: 'hello',
part2: 'world'
},
initialize: function() {
//console.log("initialize item");
}
});
var List = Backbone.Collection.extend({
model: Item,
initialize: function() {
//console.log("initialize list");
}
});
var ListView = Backbone.View.extend({
//el: $('body'), // el attaches to existing element
initialize: function(){
_.bindAll(this, 'render'); // every function that uses 'this' as the current object should be in here
this.collection = new List();
this.render();
},
render: function(){
//console.log("listview render");
},
});
var listView = new ListView();
var item1 = new Item();
listView.collection.add(item1);
console.dir("Emptying collection...");
listView.collection.each(function (item) {
console.dir("Removing model cid:" + item.cid);
listView.collection.remove(item);
})
var item2 = new Item();
listView.collection.add(item2);
var item3 = new Item();
listView.collection.add(item3);
console.dir("Emptying collection...");
listView.collection.each(function (item) {
console.dir("Removing model cid:" + item.cid);
listView.collection.remove(item);
})
console.log(listView.collection.length);
})(jQuery);
第一部分实际上是一些骨干样板文件,最后一部分应该是:
最后,listView.collection.length
应为0,但事实并非如此。
剩下一个型号。
我从控制台日志中看到,listView.collection.each(function (item) { ... })
没有做它应该做的事情,因为在第二次集合迭代中只删除一个项,而不是两个项目。
所以,我做错了什么或者某处有错误?
更新:这是jsfiddle
答案 0 :(得分:1)
您在迭代时会改变元素列表(listView.collection.remove(item)
),这通常会导致Bad Things™这是一个简化的测试用例:http://jsfiddle.net/nikoshr/Xx9uw/
在删除之前克隆模型列表:
_.each(_.clone(listView.collection.models), function (item) {
console.log("Removing model cid:" + item.cid);
listView.collection.remove(item);
});
http://jsfiddle.net/nikoshr/Xx9uw/2/
或使用collection.reset
:
listView.collection.reset();
答案 1 :(得分:0)
当我看到@ nikoshr的回答时,我知道我是个傻瓜。再次。我在不同的语言中重复同样的错误,C / C ++(通常会产生ye-olde-segfault),Java,C#等......现在JS / BB。
该死。
除了nikoshr的答案之外,我发现这个基于集合的解决方案可以避免经典迭代(在C#中可以使用linq扩展来实现这一目的):
this.collection
.forEach(function (item) {
item.destroy()
});
方便的是,Underscore为您提供了过滤掉您真正需要的模型的选项:
this.collection
.where({ YourAttribute: YourValue, YourOtherAttribute: YourOtherValue })
.forEach(function (item) {
item.destroy()
});