3

I'm currently working on a prototype mobile app that should support pulling data from a server to the device, storing that data in an SQLite DB on the device, allow the user to manipulate the data, then push the data from the SQLite DB back up to the server. So far, everything is working great until the last part. I'm having trouble getting information back out of the SQLite tables and into a JSON object to push back up to the server.

My basic issue at this point is figuring out how to build a JSON object from the data in SQLite given that all db transactions in javascript are asynchronous from my understanding.

I've got a jsFiddle with some example code: http://jsfiddle.net/uu29g/

My hope is to push something up to the server that looks like this:

[{"order_num": "2001", "custnum": "ABC123", "custname": "Demo Customer", "status": "S", "id": 1, "lineitems": [{"id": 1, "line_num": "1", "part_num": "WSC599", "part_desc": 'Widget A', "qty": "2.0", "price": "15.00"}, {"id": 2, "line_num": "2", "part_num": "FFC898B", "part_desc": 'Dongle B', "qty": "1.0", "price": "32.98"},
{"id": 3, "line_num": "3", "part_num": "RQFG", "part_desc": 'Dooflatchie', "qty": "5.0", "price": "200"}]},{"order_num": "2002", "custnum": "ZXY987", "custname": "Another Customer", "status": "S", "id": 2, "lineitems": [{"id": 1, "line_num": "1", "part_num": "GHJH11", "part_desc": 'Lightsaber - Green', "qty": "1.0", "price": "1500.00"}, 
{"id": 2, "line_num": "2", "part_num": "C3P0", "part_desc": 'Protocol Droid', "qty": "1.0", "price": "9811.04"}]}]

Given the database in the jsFiddle example, what would be the best way to generate an object like the above from the SQLite data? Edit: Specifically, how do I build that object from three async queries? My current train of thought is to get a list of order numbers from the order_header table (in my jsFiddle example), loop over those order numbers and pull the order_header info and order_detail/line item info from the tables for each order and push that into an object, then push each order object into a final array/object. Where I'm struggling is with how to get the header and detail data from SQLite when the sql queries are asynchronous. (And I might be going about this totally wrong).

*FYI: I'm still learning about Deferred objects in jQuery. The app I'm working on is built using jQuery Mobile, and meant to work on iOS/Android and will be turned into a native app via phoneGap

4

2 回答 2

1

你可以使用JSON.stringify。将任何 JavaScript 对象转换为字符串。

此外,如果您在jQUery ajax 请求中设置了一个 JavaScript 对象,它将作为字符串传输。

于 2012-11-28T15:50:20.550 回答
0

好的,由于网络上的一些不同来源以及大量的反复试验,我终于弄清楚了这一点。 jsFiddle 示例:

基本上我最终做的是以下几点:

  1. 运行延迟 SQL 事务来获取我需要提取的订单。
  2. 将延迟事务的结果通过管道传输到匿名函数中。
  3. 循环遍历匿名函数中的结果并填充延迟函数数组,传入我需要提取数据的订单号。
  4. 在延迟函数的延迟数组上执行 $.when.apply(null, deferreds) 函数。
  5. 在延迟数组中每个订单调用的延迟函数内部,我执行所有 SQL(通过延迟函数)作为 s $.when(...).done() 函数的一部分,并在完成回调中运行函数来处理所有延迟查询的结果,并将我生成的订单对象推送到全局数组中。

现在我只需要在第 5 步中让我的延迟函数返回一个承诺,这样我就可以在每个人都完成后对全局数组做一些事情。

我确信这可以写得更好,并且我确信我的逻辑存在潜在的缺陷,但希望如果其他人有类似的问题,这将使他们走上正轨。

无论如何,这不是世界上最干净的代码,但它可以工作(参见 jsFiddle 了解 SQL 语句、db init 等)。

var ordersArr = [];

/*
Thanks to Josh Ross's answer here for how to do SQL transactions that return a deferred object
http://stackoverflow.com/questions/8058679/wrapping-websql-executesql-calls-in-a-jquery-deferred-promise
*/
function successWrapper(d) {
//console.log(d);
return (function (tx, data) {
    d.resolve(data)

})
};

function failureWrapper(d) {
console.log("Sql failed");
return (function (tx, error) {
    d.reject(error)
})
};  



function getMyOrdersSQL() {
return $.Deferred(function (d) {
    db.transaction(function (tx) {
                    tx.executeSql(getSyncableOrdersStatement, [], 
                    successWrapper(d), failureWrapper(d));
                });
    });
}

function getHeaderDataSQL(ordernum) {
return $.Deferred(function (d) {
    db.transaction(function (tx) {
                    tx.executeSql(getOrdHeaderSingleStatement, [ordernum], 
                    successWrapper(d), failureWrapper(d));
                });
    });
}


function getDetailDataSQL(ordernum) {
return $.Deferred(function (d) {
    db.transaction(function (tx) {
                    tx.executeSql(getOrderDetStatement, [ordernum], 
                    successWrapper(d), failureWrapper(d));
                });
    });
}

function getNoteDataSQL(ordernum) {
return $.Deferred(function (d) {
    db.transaction(function (tx) {
                    tx.executeSql(getDriverNoteStatment, [ordernum], 
                    successWrapper(d), failureWrapper(d));
                });
    });
}


function getOrders() {

$.when(getMyOrdersSQL()).pipe(function(dta) {
    var deferreds = [];
    //build an array of deferred SQL transactions
    //each deferred transaction should populate an order object, then push it into the final ordersArr array
    if (dta.rows.length > 0) {
        for (var i=0; i<dta.rows.length; i++) {
            //console.log(dta.rows.item(i).order_num);
            deferreds.push(getOrdStuff(dta.rows.item(i).order_num)); //push in a function for each order in the getMyOrdersSQL resultset
        }
        $.when.apply(null, deferreds); //run all the deferred functions

    }else {
        console.log(dta.rows);  
        alert("No records found!");
    }
}).done(function() {

}).fail(function() {
    alert("Failed!");
});
}

function getOrdStuff(ordernum) {
console.log(ordernum);
return $.Deferred(function(d) {
    var orderObj = new Object(); //object to hold the order info
    //getDriverNoteStatment
    //getOrdeDetSingle
    //getOrdHeaderSingleStatement

    $.when(getHeaderDataSQL(ordernum), getDetailDataSQL(ordernum), getNoteDataSQL(ordernum)).done(
    function(dta1, dta2, dta3) {
        //dta1 is the deferred promise/result from the getHeaderDataSQL function
        //dta2 is the deferred promise/result from the getDetailDataSQL function
        //dta3 is the deferred promise/result from the getNoteDataSQL function                      
        var orderHeader = dta1.rows.item(0); 

        var orderNotes = dta3.rows.item(0);

        orderObj.order_num = orderHeader.order_num;
        orderObj.status = orderHeader.status;
        orderObj.shipto_num = orderHeader.shipto_num;
        orderObj.po_num = orderHeader.po_num;
        orderObj.billto_num = orderHeader.billto_num;


        var onObj = new Object(); //order notes object
        orderObj.notes = orderNotes.notes;
        orderObj.notes_dtstamp = orderNotes.dtstamp;

        var odArr = []; //order detail array to hold order line items objects

        for (var k = 0; k<dta2.rows.length; k++) { //loop over line item results
            console.log(dta1.rows.item(0).order_num+' has '+dta2.rows.length+' line items');
            var odObj = new Object();
            var orderDetails = dta2.rows.item(k);
            odObj.line_num = orderDetails.line_num;
            odObj.part_num = orderDetails.part_num;
            odObj.qty = orderDetails.qty;
            odObj.part_desc = orderDetails.part_desc;
            odArr.push(odObj); //push each line item object into the detail array

        }           

        orderObj.lineitems = odArr;
        ordersArr.push(orderObj);
        console.log("got stuff");
        console.log(ordersArr);
        return function(d) {
            d.resolve();    //return the promise
        }

    }).fail(function(etx, err) {
         d.reject(err, etx) //return the error if any transaction failed
    });


});


}
于 2012-12-13T19:58:13.490 回答