1

所以我有一个包含一些其他视图的视图,这些视图都是使用循环添加的。问题是我想为每个视图绑定不同的事件,并且由于某种原因,似乎只有最后一个事件被添加到所有视图中(或者更好的是,它覆盖了以前的事件)。

代码实际上很简单,我只是不明白为什么当我在“card”控制器上调试时我的变量“params”总是字母“S”:

    var stores = ["B", "O", "E", "K", "S", "F"];
    for(var i = 0 ; i < 5 ; i++ )
{
    var view_b = Titanium.UI.createView
    ({
       backgroundColor:'#92b723',
       top:0,
       height:200,
       width:200,
       borderRadius: 30
       // layout:'horizontal'
    });

    // Handle event
    var params = stores[i];   
    view_b.addEventListener('click', function(e) {
            var controller = Alloy.createController("card", params).getView();
            controller.open();          
    });

    $.carouselView.add(view_b);

        ... (some other stuff)
  }

应该发生的是,每当我单击任何视图时,它都会将我带到卡片视图并显示我单击了哪个字母。现在代码的方式是通过单击任何视图得到一个“S”。

提前致谢。

4

2 回答 2

1

JavaScript 范围混淆的经典案例。发生的事情是事件侦听器引用的 for-loop 范围正在发生变化,因此您i的每个事件侦听器始终为 5,因为它是创建的最后一个范围,因此您始终为每个事件侦听器获得“S”。

首先,在 for 循环中创建事件侦听器不是一个好习惯(主要是因为这个范围/上下文的东西),试试这个,将你的函数分成一个命名函数,然后将 params 值与你的视图一起传递。这样你就可以明确定义你的值属于哪个范围(视图),而不是让 JavaScript 对你做一个数字:

var stores = ["B", "O", "E", "K", "S", "F"];

// 1 - Name your event listener function
// This is a good idea anyway so that you can remove the listener later
function listener(e) {
    var controller = Alloy.createController("card", e.source.params).getView();
    controller.open();
}

for (var i = 0; i < 5; i++) {
    var view_b = Titanium.UI.createView({
        backgroundColor : '#92b723',
        top : 0,
        height : 200,
        width : 200,
        borderRadius : 30,
        // Pass your parameter with the view itself, more explicit
        params : stores[i]
    });

    view_b.addEventListener('click', listener);

    $.carouselView.add(view_b);
}
于 2013-10-17T01:29:08.073 回答
0

您必须从循环中删除事件侦听器,并将其包装在循环外的函数中。就像是:

function listenerHelper(view, params) {
 view.addEventListener('click',function(e) {
  var controller = Alloy.createController("card", params).getView();
  controller.open();
 }
}

然后在循环中调用该函数,并将正确的参数传递给它。

于 2013-10-16T21:51:52.683 回答