我有一个从远程源填充的tableView。我动态地在每一行上添加几个按钮,每行的按钮和内容都在for循环中。我在按钮侦听器中有一个警告对话框侦听器。一旦出现,如果选择确认(是),我希望能够更改按钮标题。
我收到以下错误:
Uncaught TypeError: Cannot set property 'title' of undefined.
这是错误的来源:
btn[i].title = "Finish"
对不起,我目前无权访问该代码,并且没有给予太多帮助,但是我们将非常感谢任何帮助/想法......
编辑:
虚拟代码:
var btn = new Array();
btn[i] = Ti.UI.createButton({
backgroundImage: '/images/button.png',
title:'Start',
top: 0,
left: 0,
height: '20%',
width: '20%'
});
btn[i].addEventListener('click', function(e){
var alert = Titanium.UI.createAlertDialog({
title : 'Dialog',
message : 'Change Title',
buttonNames : ['Yes', 'No']
});
alert.addEventListener('click', function(e) {
if(e.index == 0) {
btn[i].title = "Finish";
}
});
alert.show();
});
tableViewRow.add(btn[i]);
答案 0 :(得分:1)
在某处你有for
这样的循环:
for( i = 0; i < btn.length; i++ ) {
// do stuff with btn[i]
}
将其更改为:
for( i = 0; i < btn.length; i++ ) {
addButton( btn[i] );
}
function addButton( button ) {
// do stuff with button
}
addButton()
函数的正文将是for
循环中的所有代码,但有一点不同:您所拥有的任何地方btn[i]
都会将其更改为button
。
通过将此代码移动到一个函数中,您可以创建一个“闭包”,只要需要就保留button
变量的值,这与循环结束后btn[i]
变为无效的原始代码不同。运行
请记住,在设置完成的原始代码之后很久就会调用事件侦听器。如果在事件侦听器中使用循环索引,则该索引值不是您期望的值。闭合装置以非常简洁的方式解决了这个问题。
您在评论中提到您还需要循环索引。在这种情况下,你可以这样做:
for( i = 0; i < btn.length; i++ ) {
addButton( i );
}
function addButton( i ) {
// do stuff with btn[i]
}
实际上,现在您不必更改循环体/函数体中的任何代码。您仍然可以像以前一样使用btn[i]
。
或者,你可以这样做:
for( i = 0; i < btn.length; i++ ) {
addButton( button, i );
}
function addButton( button, i ) {
// do stuff with button (instead of btn[i]) and i where needed
}
现在,您可以将btn[i]
函数中的所有addButton()
引用替换为button
,如第一个示例所示,并且在需要时仍然可以使用i
。
答案 1 :(得分:0)
你在for循环中在i上创建了一个闭包。当循环退出时,所有创建的函数都将在同一个var i上有一个闭包,该值对于所有函数都是“length”,因此是未定义的。