2015-11-06 52 views
0

我想在我的角度工廠建立一個數據庫:角廠返回null

angular.module("App") 

.factory("DatabaseFactory", function() { 
    var database = null; 
    var factory = {}; 

    factory.getDatabase = function() { 
     if (database == null) { 
      window.sqlitePlugin.openDatabase({ 
       name: "myDB.db", 
       androidDatabaseImplementation: 2, 
       androidLockWorkaround: 1 
      }, function (db) { 
       database = db; 

       database.transaction(function (transaction) { 
        transaction.executeSql(create_user, [], function (transaction, result) { 
         console.log("table user created: " + JSON.stringify(result)); 
        }, function (error) { 
         console.log("table user error: " + error.message); 
        }); 
       }, function (error) { 
        console.log("transaction error: " + error.message); 
       }, function() { 
        console.log("transaction ok"); 

        return database; 
       }); 
      }); 
     } else { 
      return database; 
     } 
    } 

    return factory; 
}); 

數據庫作品的創作,交易也行。我現在提供的服務與功能,以初始化數據庫:

angular.module("App") 

.service("DatabaseService", function (DatabaseFactory) { 
    var database; 

    function initDatabase() { 
     console.log("init before database: " + JSON.stringify(database)); 

     database = DatabaseFactory.getDatabase(); 

     console.log("intit after database: " + JSON.stringify(database)); 
    } 

    return { 
     initDatabase: function() { 
      initDatabase(); 
     } 
    }; 
}); 

它被調用設備上的準備:

angular.module("App", ["ionic", "ngCordova", "App.Home"]) 

.config(function ($stateProvider, $urlRouterProvider) { 
    $stateProvider.state("app", { 
     url: "/app", 
     abstract: true, 
     templateUrl: "templates/main.html" 
    }); 

    $urlRouterProvider.otherwise("/app/home"); 
}) 

.run(function ($rootScope, $ionicPlatform, DatabaseService) { 
    $ionicPlatform.ready(function() { 
     console.log("ionic Ready"); 

     if (window.cordova && window.cordova.plugins.Keyboard) { 
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); 
     } 

     if (window.StatusBar) { 
      StatusBar.styleDefault(); 
     } 

     DatabaseService.initDatabase(); 
    }); 
}); 

日誌輸出:

init before database: + undefined 
init after database: + undefined 

這樣的回報我的工廠數據庫返回未定義,但我不知道爲什麼。它應該返回數據庫,因爲它已正確初始化。

回答

1

您不能從函數返回數據庫,因爲接收它的函數是異步回調函數。

如果整個函數是同步的(例如,不執行任何異步工作,如從文件讀取,連接到數據庫,網絡請求,套接字等),則只能使用return語句。

在你的情況,window.sqlitePlugin.openDatabase做一些異步工作方式和asks for a callback as the second argument。此回調將在數據庫連接打開後調用,這將在您的getDatabase函數返回值之後調用。

window.sqlitePlugin.openDatabase({ 
    name: "myDB.db", 
    androidDatabaseImplementation: 2, 
    androidLockWorkaround: 1 
}, function (db) { 
    database = db 
    // this happens at some point in the future 
}); 

// this happens straight away 
// at this point database is still undefined 
return database; 

測試這個以供將來參考的一個好方法是使用console.log,看在什麼時間和你的代碼運行順序。

window.sqlitePlugin.openDatabase({ 
    // ... 
}, function (db) { 
    database = db 
    console.log('A'); 
}); 

console.log('B'); 
return database; 

你會看到,而不是語句的排列順序執行,B是第一次登錄,然後A秒。

如果您讓getDatabase方法採用回調參數,則只要準備就緒,就可以將db對象傳入。

factory.getDatabase = function (callback) { 
    window.sqlitePlugin.openDatabase({ 
    // ... 
    }, function (db) { 
    // do some stuff with db, when you are ready 
    // pass it to the callback, with null as the 
    // first argument (because there isn't an error 
    callback(null, db); 
    }); 

然後你會重寫你的代碼來使用回調。

DatabaseFactory.getDatabase(function(err, db) { 
    console.log("intit after database: " + JSON.stringify(database)); 
}); 

您可能想知道爲什麼回調也有err參數。

在node.js中,通過將它們作爲第一個參數返回給當前函數的回調來處理異步函數中的錯誤,這被認爲是標準慣例。如果有錯誤,第一個參數傳遞的所有細節Error對象。否則,第一個參數爲空。

(從NodeJitsu

+0

非常感謝。這種回調方法是完美的解決方案。 – Mulgard

0

我想你應該

var factory = {}; 

更換

var database = null; 
var factory = {}; 

,做

return factory.database 

in your factory.getDatabase