无法在for循环中使用JavaScript创建SQLite表
问题描述:
我有一个使用AngularJS,JS,Phonegap/Cordova,Monaca和Onsen UI开发的跨平台应用程序。无法在for循环中使用JavaScript创建SQLite表
我已经在应用程序中实现了一个SQLite数据库来存储各种数据,以确保应用程序可以离线使用。我已经完成了一些简单的测试,并且这些都是按照预期工作的。
我现在尝试创建我需要在应用程序中的所有表(共28)在我的应用程序第一视图小号onDeviceReady()功能。为此我创建了一个对象数组,我将逐个传递给SQLite CREATE语句,如下所示。
设置表中的值
// Form values
var formValues = [{
tablename: "table_1",
id: "id_1",
desc: "desc_1",
dataType: "TEXT"
}, {
tablename: "table_2",
id: "id_2",
desc: "desc_2",
dataType: "TEXT"
}, {
...
...
...
...
}, {
tablename: "table_28",
id: "id_28",
desc: "desc_28",
dataType: "TEXT"
}];
创建表
function onDeviceReady() {
for (var i = 0; i < formValues.length; i++) {
var createFormValues = 'CREATE TABLE IF NOT EXISTS ' + formValues[i].tablename + ' (' + formValues[i].id + ' INTEGER, ' + formValues[i].desc + ' ' + formValues[i].dataType + ')';
alert("SQL: " + createFormValues +
"\n\nForm: " + formValues +
"\nName: " + formValues[i].tablename +
"\nID: " + formValues[i].id +
"\nDesc: " + formValues[i].desc +
"\nType: " + formValues[i].dataType);
db.transaction(function (tx) { tx.executeSql(createFormValues); });
}
};
当我运行上面的代码,警报显示,所有包括SQL语句中的信息OK 。但是,当我查询for()循环后面的每个表时,它表示没有创建表最后一个表除外。
然后,我尝试以下哪个DOES创建所有的表,但显然效率低下和管理。
调用函数
createFormTables("table_1", "id_1", "desc_1", "TEXT");
createFormTables("table_2", "id_2", "desc_2", "TEXT");
createFormTables("...", "...", "...", "...");
createFormTables("table_28", "id_28", "desc_28", "TEXT");
执行功能
createFormTables: function (tableName, id, description, dataType) {
var sql = 'CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + id + ' INTEGER, ' + description + ' ' + dataType + ')';
alert("Create Form Field SQL: " + sql);
db.transaction(function (tx) { tx.executeSql(sql); });
},
我知道SQLite的语句是异步执行的,但我不明白为什么会在第二个创建表例如,而不是第一个?如何使用第一个示例创建表?我可以设置一个$ timeout来执行每个INSERT声明,但这似乎没有必要,并且会导致延迟。
答
我会使用JavaScript的“对象”的形式给出,以避免冲突调用函数“createFormTables”喜欢的东西时:然后在代码
var QuerySet = function(){
//OPTIONAL: I use JQuery Deferred to catch when an async event has finished
this.defRes = new $.Deferred();
this.defResProm = this.defRes.promise();
};
QuerySet.prototype.createFormTables= function(inputData){
//do your stuff and manage when this.defRes is resolved and results it sends back (if a result is needed)
this.sqlToExecute = "// YOUR SQL QUERY";
var self=this;
$.when(
(new SqlResult(this.sqlToExecute)).execSqlCustomDeferred(), //read below for SqlResult() explanations
self
).done(function(sqlRes,self){
self.defRes.resolve();
});
return this.defResProm;
};
:
creatFromTables[i] = (new QuerySet()).createFormTables(inputData);
createFromTables[i].defRes.done(function(res){//do stuff with the result});
不需要使用$ .Deferred(),但我认为它可能是有用的,如果你想知道什么时候所有的表已经创建。
这里是用来调用数据库本身的交易SQLRESULT:
var SqlResult = function(sqlToExecute,bracketValues){
//console.log("SqlResult("+sqlToExecute+','+bracketValues+') starts');
this.sqlToExecute = sqlToExecute;
this.bracketValues =bracketValues;
};
SqlResult.prototype.execSqlCustomDeferred = function(){
var execSqlCustomDeferredRes = $.Deferred();
var execSqlCustomDeferredResProm = execSqlCustomDeferredRes.promise();
//console.log("SqlResult.execSqlCustomDeferred sqlToExecute is: "+this.sqlToExecute);
var sqlToExecuteForTx = this.sqlToExecute;
var bracketValuesForTx = this.bracketValues;
DbManagement.db.transaction(function(tx){
console.log("SqlResult.execSqlCustomDeferred in TX sqlToExecute is: "+sqlToExecuteForTx);
if(bracketValuesForTx!=null){
console.log("SqlResult.execSqlCustomDeferred bracket value is: "+ArrayManagement.arrayToString(bracketValuesForTx));
}
tx.executeSql(sqlToExecuteForTx,bracketValuesForTx,success,error);
function success(tx,rs){
//console.log('before execSqlCustomDeferredRes resolve ' + execSqlCustomDeferredRes.state());
execSqlCustomDeferredRes.resolve(rs);
//console.log('before execSqlCustomDeferredRes resolve after ' + execSqlCustomDeferredRes.state());
}
function error(tx,error){
console.log('execSqlCustomDeferred error ' + error.message);
execSqlCustomDeferredRes.reject(error);
}
});
return execSqlCustomDeferredResProm;
};