2016-09-16 88 views
0

我有一個使用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聲明,但這似乎沒有必要,並且會導致延遲。

回答

1

我會使用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; 
};