最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - this.each not iterating through collection correctly - Stack Overflow

programmeradmin4浏览0评论

I've just started using backbone.js and I'm adding some basic methods to extend a collection allowing me to iterate through a collection and save all models, and iterate through a collection to destroy all models. I realise that bulk updates aren't RESTful, but I'm only updating to local storage so didn't think it would be an issue to do multiple updates.

In my base application, the collection has 9 models. When I call collection.saveModels() it correctly logs the length of the collection, and correctly saves all the models.

When I call collection.deleteModels() it correctly logs the length of the collection, but skips every second model (i.e. the 2nd, 4th, 6th, 8th). Each time delete is pressed it continues to only delete the odd indexed element, with the last item to be deleted being the 8th original item.

Is it possible I'm using the each function incorrectly, despite it working perfectly when I save?

_.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();
    });
}
});

and they are called like so: mycollection.saveModels(); and mycollection.deleteModels();

I realise I can iterate through the collection based on length, but I'd rather use the built in method where possible.

I've just started using backbone.js and I'm adding some basic methods to extend a collection allowing me to iterate through a collection and save all models, and iterate through a collection to destroy all models. I realise that bulk updates aren't RESTful, but I'm only updating to local storage so didn't think it would be an issue to do multiple updates.

In my base application, the collection has 9 models. When I call collection.saveModels() it correctly logs the length of the collection, and correctly saves all the models.

When I call collection.deleteModels() it correctly logs the length of the collection, but skips every second model (i.e. the 2nd, 4th, 6th, 8th). Each time delete is pressed it continues to only delete the odd indexed element, with the last item to be deleted being the 8th original item.

Is it possible I'm using the each function incorrectly, despite it working perfectly when I save?

_.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();
    });
}
});

and they are called like so: mycollection.saveModels(); and mycollection.deleteModels();

I realise I can iterate through the collection based on length, but I'd rather use the built in method where possible.

Share Improve this question edited Aug 7, 2015 at 11:54 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Jun 20, 2011 at 6:51 djlumleydjlumley 2,9672 gold badges26 silver badges30 bronze badges 4
  • 3 the main problem, in general, with deleting things in loops is that it messes up where the loop currently is - the length of the loop gets shortened, and the "next" item index actually refers to the item after the next one - for example, if you delete the first item, the next index for the loop would be the second item, but what was the second item is now the first - so the third item is now the second - hope that makes sense – kinakuta Commented Jun 20, 2011 at 6:54
  • Ah, that's it. Didn't even think about that! – djlumley Commented Jun 20, 2011 at 6:55
  • 1 Seems you would need to loop using length, but loop backwards in any case – mplungjan Commented Jun 20, 2011 at 7:39
  • @kinakuta you should write that as the answer. I believe it's correct – Pablo Fernandez Commented Jun 21, 2011 at 3:57
Add a ment  | 

4 Answers 4

Reset to default 8

The code bradgonesurfing posted doesn't actually work as the clone method doesn't return an underscore object. The correct way is to use the _.chain method with makes each method chainable.

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

The code below worked great for me:

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

Every time you call model.destroy() it removes itself from the collection. The each iterator doesn't know this. Do something like the following.

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

Backbone has access to underscore.js utils. First clone the models array then iterate over that and then destroy each model. Should work

This is the implementation of kinakuta's ment I ended up using.

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

评论列表(0)

  1. 暂无评论