简体   繁体   English

将事件侦听器传递给事件侦听器?

[英]Passing event listener in to event listener?

I have a tableView that is populated from a remote source. 我有一个从远程源填充的tableView。 I add several buttons on each row dynamically, buttons and content of each row are in a for loop. 我在每行上动态添加了几个按钮,每行的按钮和内容位于for循环中。 I have an alert dialog box listener within the button listener. 我在按钮侦听器中有一个警报对话框侦听器。 Once this appears if confirm (YES) is selected I want to be able to change the button title. 一旦出现此对话框(如果选择确认(是)),我希望能够更改按钮标题。

I receive the following error: 我收到以下错误:

        Uncaught TypeError: Cannot set property 'title' of undefined.

This is the source of the error: 这是错误的来源:

        btn[i].title = "Finish" 

Sorry I don't have access to the code at the moment and haven't gave much to work with but any help/ideas would be greatly appreciated... 抱歉,我目前无法访问代码,并且工作量不多,但是任何帮助/想法都将不胜感激...

EDIT: 编辑:

Dummy code: 虚拟代码:

        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]);

Somewhere you have a for loop like this: 在某个地方有这样的for循环:

for( i = 0;  i < btn.length;  i++ ) {
    // do stuff with btn[i]
}

Change it to: 更改为:

for( i = 0;  i < btn.length;  i++ ) {
    addButton( btn[i] );
}

function addButton( button ) {
    // do stuff with button
}

The body of the addButton() function will be all of the code that was in your for loop with one difference: everywhere you have btn[i] change it to button . addButton()函数的主体将是for循环中的所有代码,唯一的区别是: btn[i]到处都将其更改为button

By moving this code into a function, you create a "closure" which preserves the value of the button variable as long as needed, unlike the original code where btn[i] becomes invalid after the loop finishes running. 通过将此代码移入函数中,可以创建一个“闭合”,该闭合将根据需要保留button变量的值,这与原始代码不同,在循环结束后, btn[i]变为无效。

Remember that event listeners are called long after the original code that sets them up finishes. 请记住,在设置事件侦听器的原始代码完成很久之后才调用事件侦听器。 If you use a loop index in the event listener, that index value is not the one you expect. 如果在事件侦听器中使用循环索引,则该索引值不是您期望的值。 The closure fixes this in a very clean and simple way. 封盖以非常干净和简单的方式解决此问题。

You mentioned in a comment that you need the loop index as well. 您在注释中提到还需要循环索引。 In that case you could do this: 在这种情况下,您可以这样做:

for( i = 0;  i < btn.length;  i++ ) {
    addButton( i );
}

function addButton( i ) {
    // do stuff with btn[i]
}

In fact, now you don't have to change any of the code in the loop body/function body. 实际上,现在您不必更改循环主体/函数主体中的任何代码。 You can still use btn[i] as before. 您仍然可以像以前一样使用btn[i]

Or, you can do it this way: 或者,您可以通过以下方式进行操作:

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
}

Now you can replace all the btn[i] references inside the addButton() function with button as in the first example, and you still have i available when you need it. 现在,您可以像在第一个示例中一样,用button替换addButton()函数内的所有btn[i]引用,并且在需要时仍可以使用i

you are creating a closure on i within a for loop. 您正在for循环中在i上创建一个闭包。 When the loop exit, all created functions will have a closure on the very same var i, which value will be "length" for all functions, hence the undefined. 当循环退出时,所有创建的函数将在完全相同的var i上有一个闭包,对于所有函数,该值均为“ length”,因此未定义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM