所以我有一个包含一些其他视图的视图,这些视图都是使用循环添加的。 问题是我想为每个视图绑定不同的事件,并且出于某种原因,似乎只有最后一个事件被添加到所有视图中(或者甚至更好,它会覆盖先前的事件)。
代码实际上非常简单,我只是不明白为什么当我在“卡”控制器上调试时,我的变量“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”。
提前致谢。
答案 0 :(得分:1)
JavaScript范围混淆的经典案例。发生的事情是事件侦听器引用的for循环范围正在发生变化,因此每个事件侦听器的i
始终为5,因为它是最后创建的范围,因此每个事件总是得到“S”事件监听。
首先,在for循环中创建事件侦听器并不是一个好习惯(主要是因为这个作用域/上下文的东西),试试这个,将你的函数分成命名函数,然后在你的视图中传递params值。这样你就明确定义了ee属于哪个范围(视图),而不是让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);
}
答案 1 :(得分:0)
您必须从循环中删除事件侦听器,并将其包装在循环外的函数中。类似的东西:
function listenerHelper(view, params) {
view.addEventListener('click',function(e) {
var controller = Alloy.createController("card", params).getView();
controller.open();
}
}
然后在循环中调用该函数,并将正确的参数传递给它。