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

时间:2015-07-08 02:39:47

标签: javascript backbone.js

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

jQuery("#requestStatusChart").mouseover(function (event) {
  var maskVal = '<span id="floatTip" style="position:absolute"><span id="hintdivlogistics" class="RMAHintdivlogistics">' +
  +'</span><div class="clear"></div></span>';
  jQuery(this).find(".DashboardMask").append(maskVal)
  ShowHintInfoLogistics("abc");

  //when onmouse out ,remove the elements I appended before.
  jQuery(this).find(".DashboardMask").mouseout(function () {

    if (typeof jQuery("#hintdivlogistics") != undefined) {
      jQuery("#floatTip").fadeOut("slow").remove();
    }
  });

  //move current row
  jQuery(this).find(".DashboardMask").mousemove(function (event) {

    _xx = event.clientX;
    _yy = event.clientY;

    _yyPage = event.pageY;

    var pos = jQuery(this).position();
    console.log((pos.left + " " + pos.top));

    jQuery("#floatTip").css({ "top": _yy + "px", "left": _xx - 180 + "px",
        "border": "2px solid red"
    }).fadeIn("slow");
    console.log("x:" + _xx + ",y:" + _yy / _yyPage * _yy);

    return false;
  });

  return false;
});

2 个答案:

答案 0 :(得分:2)

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

解决方案是强制i在具有您想要的值时进行评估(即,当您构建回调函数时评估i)。有各种各样的解决方案,它们的所有变体都包含在一个功能中以打破参考&#34;主题:

  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));
    
  4. 它们都做了几乎相同的事情:在混合中添加一个额外的函数调用,以便在循环的每次迭代中强制i被评估(而不是仅仅被引用)。

    在Backbone的情况下, 1 可能是最自然的,你甚至不需要麻烦i

答案 1 :(得分:0)

另一个解决方案是使用async.each或async.eachSeries而不是async.parallel。使用前两个避免了完全推送到一系列函数。