0

我无法理解这里出了什么问题。我从数据库中获取事件列表,并尝试创建一个自定义列表来显示它们,并使用回调 onclick 方法。我得到了正确的值,我正确地显示了它们,但是 onClick 方法获取了最后一个项目 ID 的值,而不是它自己的值。

因此,如果我单击列表中的任何项目,我的警报会显示

show itinerary for event: 10

而不是正确的 ID(我现在有 10 个事件)

这就是我处理从数据库获得的项目的方式:

function gotEvents(transaction, result) {
             var eventList;
             var myDbElements = $('#myDbElements');            
             var params = {
                items:result.rows.length,
                hasImage:false,
                content:[]
             }
                   if (result != null && result.rows != null) {

                       for (var i = 0; i < result.rows.length; i++) {
                          var row = result.rows.item(i);
                          var rowText = row["Name"] + '<br/>' +  row["Start"].slice(0,9);                    


                          var rowId = row["id"];
                          var contentItems = {
                            text: rowText,
                            onClick: function(){ showEventItinerary(rowId) }

                          }
                           params.content.push(contentItems);                      
                          }
                          for (var j=0; j<result.rows.length;j++){
                            PrecAppPersistence.debugObject(params.content[i]);
                          }
                          eventList = PrecAppComponents.myList(params,$('#eventsList'));
                   }
                PrecApp.I_SCROLL.refresh();   
               }


            function showEventItinerary(event_ID) {
                alert("show itinerary for event:"+event_ID);
            }

这是我创建列表的方式:

function List() {

var self;
var items;
var firstRun = true;

this.initialize = function(params,cont) {
    self = this;
    var container = cont;

    var items;
    container.empty();
    opt = {
            items:0,
            content:[], // array with the content. Default is = {text:text,icon:imageURL,onClick: function(){}}  itemId // not sure if we need this yet. supposed to be a manual ID for the item. EX: id taken from the db.                                         
            width: 300,
            hasImage: false, //set true if you want to show an images
            margin:10, //margin between items               


    }
    for (i in params) opt[i] = params[i];

    items = opt.items;
    container.width(opt.width);

    for (i=0;i<items;i++){

        itemToAdd = '<div class="listItem" id="listItem'+i+'">'; //add IDS to add click                        
        if (opt.hasImage) {
            itemToAdd += "<img src=" + opt.content[i].image + " />";
        }               
        itemToAdd += "<p>" + opt.content[i].text + "</p>";
        itemToAdd += "<div class='clearFix'></div>";
        itemToAdd += '</div>';      
        container.append(itemToAdd); //original #scroller might change?     

        listItem = $('#listItem'+i);    
        listItem.css('margin',opt.margin + 'px 0');
        listItem.on('click',opt.content[i].onClick);            

    }


}}

我正在记录我的变量,我的 rowId 具有正确的 ID。onClick 日志显示所有项目的以下内容:

onClick:function (){ showEventItinerary(rowId )}(我不确定这是否正确,它不应该显示 rowID 的值而不是变量 rowID 吗?)

我在这里错过了什么吗?

谢谢

4

2 回答 2

1

您需要创建一个闭包,因为您的索引 i 使用循环更新:

for (var i = 0; i < result.rows.length; i++) {(function(index){
// use index instead of i inside your loop
...
// end closure
})(i);
// end loop
}

自调用函数将使用 index=i 执行。i 是循环的一部分,它的值会改变,而循环中的每个函数都将保留自己的索引。

于 2012-11-21T18:07:19.757 回答
1

没有块级范围,rowID要么使用数组将每个项目存储在循环中,要么使用 aclosure为每次迭代创建单独的范围。

检查臭名昭著的循环问题

于 2012-11-21T18:26:06.553 回答