如何在交易回调函数中传递参数

3
从像这样的教程代码开始
function queryDB(tx) {
    tx.executeSql('SELECT * FROM DEMO', [], querySuccess, errorCB);
}

function querySuccess(tx, results) {

}

function errorCB(err) {
    alert("Error processing SQL: "+err.code);
}

var db = window.openDatabase("Database", "1.0", "PhoneGap Demo", 200000);
db.transaction(queryDB, errorCB); 

在 db.transaction 中,我想把一个变量作为参数传递给 queryDB 函数,所以我认为代码应该是这样的:

db.transaction(queryDB(id), errorCB);

我该如何实际应用它?还是说它就像这样工作,我的id会被传递并进入tx?
6个回答

6
将其再次包装在一个函数中。
var id = 'THEID';
db.transaction(function(){
  queryDB(id)
}, errorCB);

注意 - 这是假设您正在创建API。一些API / 框架会自动插入所需的信息。例如:
//the db.transaction method
function transaction(param, callback) {
   //do code stuff
   callback(someInternalId); //callback is the function you pass as the first parameter
}

因此,如果你想在回调函数中传递自己的数据,请将其包装在一个函数中。否则,你正在使用的代码可能会自动为你完成这个操作。


那么在 queryDB() 函数中,我可以通过 tx.id 获取 id 值吗?* 我正在开发 PhoneGap。 - cjmling
就像我说的那样,这取决于PhoneGap的API(我没有使用过它)。 tx是您想传递给queryDB的值还是您期望API填充的方法(例如交易ID)? 如果您想一起传递它,可以使用我上面详细介绍的方法。 - JohnP
tx 可能是一个方法,API 将填充它,我猜测。http://dev.w3.org/html5/webdatabase/#sqltransactioncallback.... 所以如果我想传递它,那么我如何检索 ID 的值呢?是通过 tx.id 吗? - cjmling
好的,您关于通过将数据包装在函数中传递来帮助我解决问题的答案,帮了我另一种方式。谢谢:D - cjmling
请查看我的答案,它会给你所需的确切功能。 - TheTechy
显示剩余2条评论

6

我喜欢保持简单,所以在处理能够接收参数的phonegap应用程序存储时,我仅使用有限数量的函数。我看到的很多例子都调用许多子函数,对我来说,在调试时这是一场噩梦。

我在Web SQL方面遇到了许多问题,但阅读规范确实非常有帮助,可以澄清我可以和不能做什么。(http://www.w3.org/TR/webdatabase/

请看下面这个插入函数的简单代码:

function dbInsert(param1, param2, dbObj) {
    val1 = param1;
    val2 = param2;
    val3 = String(dbObj.item2);

    var sqlTxt = "INSERT INTO demo (geo1, geo2, geo3) VALUES (?, ?, ?)";
    db.transaction(function(tx) {tx.executeSql(sqlTxt,[val1,val2,val3])}, errorCB, successCB);
    }

让我们来看看这个过程。显然,这是一个接收任何参数的标准函数,在本例中是一个对象和字符串。

sqlTxt 是一个有趣的地方。像通常写插入语句一样编写它,但在 VALUES 中通常需要插入/选择等数据的位置使用 ? 占位符,为要传递数据的数据库表中的每个字段使用 ?。

现在让我们分解下一行:

db.transaction(function(tx) {tx.executeSql(sqlTxt,[val1,val2,val3])}, errorCB, successCB);

当您创建新数据库时,db是处理数据库对象的句柄,因此db.transaction要求在数据库db上执行事务。

如果我们像这样编写下一节,您可以看到它是调用tx.executeSql的函数,并且由于它在db.transaction方法内部执行,因此将传递db句柄。

function(tx) {
    tx.executeSql(sqlTxt,[val1,val2,val3])
}

现在,如果我们解析sqlTxt,它可能看起来像这样。
INSERT INTO demo (geo1, geo2, geo3) VALUES ('a', 'b', 'c');

因为我们将三个变量代替?占位符传递,所以它看起来像上面的一行。最后,您调用错误和成功回调函数。

在您的情况下,我会创建一个像这样的queryDB函数:

function queryDB(id) {
    var sqlTxt = "SELECT * FROM DEMO WHERE id=?"
    db.transaction(function(tx) {tx.executeSql(sqlTxt,[id])}, errorCB, successCB);
}

本质上,该函数获取参数id,并将其传递到查询中的[id]中执行并返回错误或成功。显然,您可以扩展此功能以使用多个参数,或者如果您想变得非常聪明,只需创建一个单一的数据库事务函数,并将要使用的sql和参数作为对象或数组传递(示例将在我的博客上发布这个周末)


2

首先创建一个处理数据库实例(数据库更新等)的类,该类将保存您将用于所有查询的函数。

self.db = window.openDatabase( // and so on

然后该函数:

    // execute a query and fetches the data as an array of objects
self.executeQuery = function(string, args, callback, callbackparams) {
    var self = this;
    //console.log('db execute: '+string);
    self.db.transaction(function(tx) {
        tx.executeSql(string, args, function(tx, result) {
            var retval = [];
            for (var i = 0; i < result.rows.length; ++i) {
                retval.push(result.rows.item(i));
            }
            if (callback) {
                callback(retval, result, callbackparams);
            }

        }, self.error);
    });
}

然后当您初始化类(我将其命名为myDb)时,就可以开始了!

myDb.executeQuery('select l.* from location l inner join item_location il on (il.location_id = l.id and il.item_id = ?)', [item.id], function(locations, res, item){
                item.locations = locations;
                myDb.executeQuery('select * from media where item_id = ?', [item.id], function(media, res, item){
                    item.media = media;
                    // create item.
                    createItem(item);                       
                }, item);
            }, item);

正如您所看到的,executeQuery有4个参数:

  • 查询语句
  • 查询参数
  • 回调函数(带有3个参数:结果、状态和myparam)
  • myparam(用于回调函数)

我花了一些时间来修复这个问题,但是一旦您完成了这个操作,就不会再出现令人讨厌的数据库错误!


谢谢你的解释,Rene,但是你能解释一下为什么要调用两个查询吗?你有一个简单的例子吗? - user1502390

0

我认为每个人都接近回答你的问题了。实际上,你需要对JohnP的回答进行轻微修改。您应该传递SQLTransaction对象,该对象包含executeSQL函数。因此,在John的回答基础上:

var id = 'THEID';
db.transaction(function(tx){
  queryDB(tx, id)
}, errorCB);

然后在定义函数的地方,您可以使用额外的变量获取id参数。

queryDB: function (tx, id) { ...your code... }

0

这是一个已解决方案:

var sqltxt= 'INSERT INTO CONTACTS(id, data) VALUES (?, ?)';
    var db = window.openDatabase("Database", "1.0", "Demo", 200000);
    db.transaction(function(tx){tx.executeSql('DROP TABLE IF EXISTS CONTACTS');
            tx.executeSql('CREATE TABLE IF NOT EXISTS CONTACTS(name unique, password)');

            tx.executeSql(sqltxt,[name, pass]);

    }, errorCB, successCB);

0

我们无法像“queryDB(id)”这样为queryDB函数发送任何参数。

我通过以下方式解决了这个问题。

var contactId = 33
dbInst.transaction(function(tx){
    tx.executeSql('CREATE TABLE IF NOT EXISTS CONTACT_REFERENCE (id unique)');
    var sqlStr = 'INSERT INTO CONTACT_REFERENCE (id) VALUES (?)'
    tx.executeSql(sqlStr, [contactId]);
}, errorCB, successCB);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接