1

我希望将一些 JSON 内容从 Drupal 网站存储到 PhoneGap 应用程序中的数据库表中。我正在使用 ajax 来执行此操作。当我运行以下代码并检查表时,我被告知它是空的。有人知道我如何填充这张表吗?

$('#newDiv').live('pageshow',function(){

    function queryDB(tx) {
        tx.executeSql("SELECT * FROM 'tableA'", [], querySuccess, errorCB);
    }

    function querySuccess(tx, results) {
        var len = results.rows.length;
        alert("Table: " + len + " rows were found.");
        }
    }

    function createTable(tx) {

        tx.executeSql('DROP TABLE IF EXISTS "tableA"');
        var sql = "CREATE TABLE IF NOT EXISTS 'tableA' (id INTEGER PRIMARY KEY AUTOINCREMENT, step VARCHAR(50), text VARCHAR(50))";
        tx.executeSql(sql, [], successCB, errorCB); 
    }

    db.transaction(createTable, errorCB, successCB);

   $.ajax({
        url: myURL,
        type: 'post',
        data: 'tid=4',
        dataType: 'json',
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert('new_page_node_view - failed to retrieve page node');
            console.log(JSON.stringify(XMLHttpRequest));
            console.log(JSON.stringify(textStatus));
            console.log(JSON.stringify(errorThrown));
        },     
        success: function (data) {

            $.each(data, function (node_index,node_value) {
               db.transaction(function(tx){
                       tx.executeSql("INSERT INTO 'tableA' (step, text) VALUES (?, ?)",[node_value.title, node_value.body]);
               });
            });
          }
      });

    db.transaction(queryDB, errorCB, successCB);


});
4

1 回答 1

4

嘿tipsch试试这个 -

  var numInserts = 0;

  $.ajax({
        url: myURL,
        type: 'post',
        data: 'tid=4',
        dataType: 'json',
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert('new_page_node_view - failed to retrieve page node');
            console.log(JSON.stringify(XMLHttpRequest));
            console.log(JSON.stringify(textStatus));
            console.log(JSON.stringify(errorThrown));
        },     
        success: function (data) {
            numInserts = data.length; // num of inserts to expect (assumes data is in array of objects)

            $.each(data, function (node_index,node_value) {
               db.transaction(function(tx){
                       tx.executeSql("INSERT INTO 'tableA' (step, text) VALUES (?, ?)",[node_value.title, node_value.body],
                       function(tx, results){
                            numInserts--; // decrement 1 from expected num of inserts
                            if (numInserts == 0){
                                db.transaction(queryDB, errorCB, successCB);
                            }
                       }, 
                       function(tx, err){
                        console.log("insert error");
                        if (err){
                            console.log(err);
                        }
                       });
               });
            });
        }
  });

/Update - 回答为什么上述方法是必要的。

好的,所以您可能想知道为什么不queryDB立即在 $.each 循环之后的 AJAX 调用的成功回调中调用,如下所示 -

   $.ajax({
        url: myURL,
        type: 'post',
        data: 'tid=4',
        dataType: 'json',
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert('new_page_node_view - failed to retrieve page node');
            console.log(JSON.stringify(XMLHttpRequest));
            console.log(JSON.stringify(textStatus));
            console.log(JSON.stringify(errorThrown));
        },     
        success: function (data) {
            $.each(data, function (node_index,node_value) {
               db.transaction(function(tx){
                    tx.executeSql("INSERT INTO 'tableA' (step, text) VALUES (?, ?)",[node_value.title, node_value.body]);
               });
            });
            db.transaction(queryDB, errorCB, successCB); // <-- the inserts could not all be finished when this gets called
        }
   });

假设您要从 JSON 结果中插入 1000 条记录。db.transaction(queryDB, errorCB, successCB);当您调用AJAX 调用成功时,这些插入不会完成。您必须对tx.executeSql插入执行成功回调,以了解插入何时完成。

我在上面的第一种方法中所做的将允许在调用queryDB函数之前完全完成所有插入。我添加了一个内联成功和失败回调到tx.executeSql("INSERT INTO 'tableA' (step, text) VALUES (?, ?)",[node_value.title, node_value.body]);. 我总是建议对 PhoneGap 中的任何 WebSQL 执行此操作(它们也不必内联)。

在我之前的工作中,我在 PhoneGap 中进行了大量的 WebSQL 事务。其中大部分涉及循环 JSON 并将其写入本地数据库表。当您有许多插入并试图在通知用户之前弄清楚它们何时全部完成时,或者在您的情况下将刚刚写入的数据拉出时,就会出现真正的困难问题。

所以......在插入的情况下你将学会做的技巧是 -

  1. 计算您期望执行的插入次数并将其存储在变量中。
  2. 在插入的成功回调中,tx.executeSql从包含您期望的插入数量的变量中减去 1。
  3. 一旦变量在tx.executeSql成功回调中变为 0,那么您就知道所有插入都已完成。

带有 1 个插入的简单示例 -

// wrong approach here
db.transaction(function(tx){
    tx.executeSql("INSERT INTO 'tableA' (step, text) VALUES (?, ?)",["foo", "bar"]);
    // it will start the select query before the insert has completed
    tx.executeSql("SELECT * FROM 'tableA'", [], querySuccess, errorCB);
});

// the right approach here
db.transaction(function(tx){
    tx.executeSql("INSERT INTO 'tableA' (step, text) VALUES (?, ?)",["foo", "bar"], insertDone, insertFail);
});

function insertDone(tx, results){
    // insert is done, now you can run the queryDB
    tx.executeSql("SELECT * FROM 'tableA'", [], querySuccess, errorCB);
}

function insertFail(tx, err){
    console.log("insert error");
    if (err){
        console.log(err);
    }
}

我希望这有助于澄清为什么我使用第一种方法而不是仅仅queryDB在 AJAX 调用的成功回调中运行。

希望这一切对未来的人有所帮助,哈哈。

于 2013-07-10T20:35:24.107 回答