0

我有以下代码:

    displayOrders: function(){
    function getRetailerName(retailerID, callback){
        var retailerName;
        db.transaction(function(qry){
            qry.executeSql("SELECT retailerName FROM retailers WHERE token = '"+retailerID+"' ", [], function(tx, results1){
                var len1 = results1.rows.length;
                var retailerName;
                for (var i1=0; i1<len1; i1++){
                    retailerName = results1.rows.item(i1).retailerName;
                    callback(retailerName);
                }
            });
        });
    }
    db.transaction(function(qry){
        qry.executeSql("SELECT * FROM orders", [], function(tx, results){
            //query was a success
            var len = results.rows.length;
            for (var i=0; i<len; i++){
                var orderTime = results.rows.item(i).orderTime;

                var retailerName;
                getRetailerName(results.rows.item(i).retailerID,function(name) { //this uses a callback function... need to because request to DB is a
                    retailerName = name ;
                    $('#orderHistoryCollapsible').append('<div data-role="collapsible" data-collapsed="false"><h3>'+retailerName+' - '+orderTime+'</h3><p>Im the collapsible set content for section 1.</p></div>');
                    $(".orderHistoryCollapsible").collapsibleset();
                    $(".orderHistoryCollapsible").collapsibleset('refresh');            
                });
            }
        });

    });     

所以基本上代码运行两个单独的数据库查询并检索要放入列表视图的数据。getRetailerName 函数提供了一个回调,该回调在下面的查询中使用,它将两组数据添加到“orderHistoryCollapsible”div。

我的问题是,也意味着插入 DOM 的 orderTime 值每次都返回循环中的最后一个值。好像这两个查询都需要作为回调提供?但是我不确定如何将数据附加到正确的位置..

任何帮助,将不胜感激

4

2 回答 2

1

该变量orderTime在函数范围 ( function(tx, results)) 中,而不是在循环范围中。这意味着,当它在 的闭包中被捕获时function(name),只有一个实例。当循环完成时,它将具有最后一次调用的值。

如果将循环体包含在匿名函数中,则可以解决此问题

for (var i=0; i<len; i++){
    function() {
        var orderTime = results.rows.item(i).orderTime;

        var retailerName;
        getRetailerName(results.rows.item(i).retailerID,function(name) { //this uses a callback function... need to because request to DB is a
            retailerName = name ;
            $('#orderHistoryCollapsible').append('<div data-role="collapsible" data-collapsed="false"><h3>'+retailerName+' - '+orderTime+'</h3><p>Im the collapsible set content for section 1.</p></div>');
            $(".orderHistoryCollapsible").collapsibleset();
            $(".orderHistoryCollapsible").collapsibleset('refresh');            
        });
    }
}

然后,每次运行主体时都有一个新范围,因此有一个新的orderTime.

于 2013-02-27T12:39:30.880 回答
1

var orderTime在您的代码中可能会产生误导,因为在 javascript 中,局部变量的范围不限于它们的封闭块(如在 Java 中),而是限于它们的封闭函数。更具体地说,你orderTime被初始化一次,然后在每次循环迭代中被覆盖(即每次都是相同的变量)。

回调函数引用该变量(称为闭包,这意味着该变量将在定义它的函数退出后存在 - 因为回调函数具有对它的引用)。当回调被调用时,循环已经完成了它的执行,所以它orderTime有它的最后一个值。

以下应该有效:

displayOrders: function(){
    function getRetailerName(retailerID, callback){
        var retailerName;
        db.transaction(function(qry){
            qry.executeSql("SELECT retailerName FROM retailers WHERE token = '"+retailerID+"' ", [], function(tx, results1){
                var len1 = results1.rows.length;
                var retailerName;
                for (var i1=0; i1<len1; i1++){
                    retailerName = results1.rows.item(i1).retailerName;
                    callback(retailerName);
                }
            });
        });
    }

    function callbackFn(orderTime) {
        return function(name) {
                $('#orderHistoryCollapsible').append('<div data-role="collapsible" data-collapsed="false"><h3>'+name+' - '+orderTime+'</h3><p>Im the collapsible set content for section 1.</p></div>');
                $(".orderHistoryCollapsible").collapsibleset();
                $(".orderHistoryCollapsible").collapsibleset('refresh');    
        };
    }

    db.transaction(function(qry){
        qry.executeSql("SELECT * FROM orders", [], function(tx, results){
            //query was a success
            var len = results.rows.length;
            for (var i=0; i<len; i++){
                var orderTime = results.rows.item(i).orderTime;
                getRetailerName(results.rows.item(i).retailerID, callbackFn(orderTime));
            }
        });

    });     
于 2013-02-27T12:44:51.257 回答