javascript - Backbone 点击事件回调中的奇怪索引问题

标签 javascript backbone.js

我有这段代码,它是独立和孤立的。我遇到的问题是索引我从 1 开始而不是从 0 开始。我不知道为什么会这样,而且似乎与我插入删除数组的闭包没有任何关系...但我不能确定,不知道问题出在哪里。

    onClickResetAll: function (event) {
                    event.preventDefault();

                    var deletes = [];

                    Object.keys(collections).forEach(function (key) {
                        if (collections.hasOwnProperty(key)) {

                            var coll = collections[key];

                            for (var i = 0; i < coll.models.length; i++) {

                                deletes.push(function (callback) {

                                    var index = i; //i starts at 1, not 0 !!!
                                    coll.models[index].deleteModel(function (err, resp, x) {

                                        console.log(err, resp, x);

                                        if(err){
                                            callback(err);
                                        }
                                        else{
                                            callback(null,null);
                                        }

                                    });
                                });
                            }

                        }
                    });

                    async.parallel(deletes,function(err,results){

                        Backbone.Events.trigger('bootRouter',  '+refreshCurrentPage');

                    });

                }, //end of onClickResetAll callback function

//end

最佳答案

问题不在于 i 从 1 开始,问题在于 i 将是 coll.models.length 删除中的函数。为什么会这样?好吧,每个函数都共享相同的 i 并且 i 不会被评估,直到 deletes 中的函数被实际调用。

解决方案是在 i 具有您想要的值时强制对其求值(即在构建回调函数时求值 i )。有多种解决方案,它们都是“将其包装在函数中以破坏引用”主题的变体:

  1. 使用带有回调函数的迭代器代替普通的 for 循环:

    coll.each(function(model, i) {
        // `model` is the model from the collection, `i` is the loop index.
    });
    

    你可以在这里使用 each 因为 Backbone collections have a bunch of Underscore functions built in .

  2. 将循环体包裹在 SIF 中:

    for(var i = 0; i < coll.models.length; ++i)
        (function(i) {
            //...
        })(i);
    
  3. 使用单独的函数来构建您的函数:

    function make_deleter(coll, i) {
        return function(callback) {
            coll.models[i].deletedModel(function(err, resp, x) {
                //...
            }
         }
    }
    
    //...
    
    for(var i = 0; i < coll.models.length; ++i)
        deletes.push(make_deleter(coll, i));
    

它们几乎都做同样的事情:在混合中添加一个额外的函数调用以强制在循环的每次迭代中评估(而不是仅仅引用)i

在 Backbone 的情况下,1 可能是最自然的,您甚至不需要使用这种方法的麻烦 i

关于javascript - Backbone 点击事件回调中的奇怪索引问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31282611/

相关文章:

javascript - 禁用然后启用 jquery 中的按钮

javascript - 如何在 InAppBrowser Cordova 中获取当前链接

javascript - Google 图表进入 JQuery Tab 绘制问题

javascript - 默认属性未在 Backbone 中的继承模型上设置

javascript - 主干内存泄漏与否?

javascript - Promise.all() 使用 Backbone 解决 IE 11

javascript - 需要了解Backbone的main函数

javascript - Backbone : Creating multiple models in a collection from a nested object

javascript - 使用动态 jQuery 选择器

javascript - 检查 Firestore Cloud 功能中的用户是否为匿名