我正在尝试将SQLite集成到我的Ionic应用程序中,但是当我尝试在数据库中查询设备上的数据时,我在通过浏览器进行远程调试或测试时不断获得Cannot read property 'transaction' of null
。
所以我把我的所有配置,控制器和工厂拆分成单独的文件,全部按功能/模块分组,所以我将每个模块的配置文件注入主应用程序,然后在配置文件中我注入了控制器和工厂。
我不确定我构建应用程序的方式是否会破坏某些内容?
下面我列出了所有相关文件,
app.js
var app = angular.module('app', ['ionic', 'ngCordova', 'app.config', 'login.config']);
app.run(['$rootScope', '$ionicPlatform', 'DB', function($rootScope, $ionicPlatform, DB) {
$ionicPlatform.ready(function() {
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
if(navigator.splashscreen) {
navigator.splashscreen.hide();
}
DB.init();
});
}]);
app.config.js
var app = angular.module('app.config', ['app.controller', 'app.factory']);
app.config(function($stateProvider, $urlRouterProvider, $httpProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'appController'
});
$urlRouterProvider.otherwise('/login');
});
app.constant('DB_CONFIG', {
name: 'database.db',
tables: [
{
name: 'users',
columns: [
{name: 'id', type: 'integer primary key'},
{name: 'username', type: 'text'},
{name: 'password', type: 'text'},
{name: 'api_key', type: 'text'},
{name: 'active', type: 'integer'}
]
}
]
});
app.factory.js
var appFactory = angular.module('app.factory', []);
appFactory.factory('DB', ['$q', '$cordovaSQLite', 'DB_CONFIG', function($q, $cordovaSQLite, DB_CONFIG) {
var db = null;
var init = function() {
db = $cordovaSQLite.openDB({ name: DB_CONFIG.name });
// I use this when testing in browser db = window.openDatabase(DB_CONFIG.name, '1.0', 'database', -1);
_.each(DB_CONFIG.tables, function(table) {
var columns = [];
_.each(table.columns, function(column) {
columns.push(column.name + ' ' + column.type);
});
var sql = 'CREATE TABLE IF NOT EXISTS ' + table.name + ' (' + columns.join(',') + ')';
console.log('Table ' + table.name + ' initialized');
query(sql);
});
};
var query = function(sql, bindings) {
bindings = typeof bindings !== 'undefined' ? bindings : [];
return $cordovaSQLite.execute(db, sql, bindings);
};
var fetchAll = function(result) {
var output = [];
for (var i = 0; i < result.rows.length; i++) {
output.push(result.rows.item(i));
}
return output;
};
var fetch = function(result) {
return result.rows.item(0);
};
return {
init: init,
query: query,
fetchAll: fetchAll,
fetch: fetch
};
}]);
login.config.js
var loginConfig = angular.module('login.config', ['ionic', 'login.controller']);
loginConfig.config(function($stateProvider) {
$stateProvider
.state('login', {
url: "/login",
templateUrl: "modules/login/views/login.html",
controller: 'loginController'
});
});
login.controller.js
var loginController = angular.module('login.controller', []);
loginController.controller('loginController', ['$scope', '$state', 'DB', function($scope, $state, DB) {
$scope.doLogin = function() {
var username = this.username;
var password = this.password;
DB.query('SELECT * FROM users WHERE username = ? and password = ?', [username, password]).then(function(result){
console.log(result);
}, function(error){
console.log(error);
});
};
}]);
用户已经插入到数据库中,有时它可以工作,我得到了结果,大部分时间都没有,我得到了上面提到的错误。
我假设这是因为在我查询数据库之前,DB没有及时初始化?
如果是这样,有没有办法在查询之前100%确定数据库已加载?
答案 0 :(得分:1)
我有同样的问题,数据库没有正确初始化(这是随机发生的),使用带延迟的promise和$ ionicPlatform.ready(function(){});
参考:https://gist.github.com/borissondagh/29d1ed19d0df6051c56f
示例:
angular.module('myapp.services', [])
.factory('DBA', function($cordovaSQLite, $q, $ionicPlatform) {
var self = this;
// Handle query's and potential errors
self.query = function (query, parameters) {
parameters = parameters || [];
var q = $q.defer();
$ionicPlatform.ready(function () {
$cordovaSQLite.execute(db, query, parameters)
.then(function (result) {
q.resolve(result);
}, function (error) {
console.warn('DB error found');
console.warn(error);
q.reject(error);
});
});
return q.promise;
}
// Process a result set
self.getAll = function(result) {
var output = [];
for (var i = 0; i < result.rows.length; i++) {
output.push(result.rows.item(i));
}
return output;
}
// Process a single result
self.getById = function(result) {
var output = null;
output = angular.copy(result.rows.item(0));
return output;
}
return self;
})
答案 1 :(得分:0)
如果只在需要时打开连接,它可能会有所帮助。 您保持连接打开,可能会超时。 我通常做的是打开一个连接,而不是查询我需要查询的内容,而不是关闭连接。
答案 2 :(得分:0)
我有同样的问题删除你的sqlLite插件并再次添加它 问题解决了!!!
cordova插件rm io.litehelpers.cordova.sqlite cordova插件添加io.litehelpers.cordova.sqlite
答案 3 :(得分:0)
$ cordovaSQLite.openDB现在需要一个强制位置参数。变化
db = $cordovaSQLite.openDB({ name: DB_CONFIG.name });
到
db = $cordovaSQLite.openDB({ name: DB_CONFIG.name, location:'default' });
答案 4 :(得分:0)
我有同样的问题。不知道为什么,但它与键盘插件有某种关联。
尝试:
@RunWith(Cucumber.class)
@CucumberOptions(plugin = { "pretty" }, features = { "<path_to_feature>" },
glue = { "<optional_steps_location_java_file>" }, dryRun = true,
tags = { "<optional_NOT_req_for_now>" })
public class RunMyCucumberTest {
}
执行此操作后数据库工作正常。
答案 5 :(得分:0)
尝试再次安装SqlLite。
ionic cordova plugin add cordova-sqlite-storage
npm install @ionic-native/sqlite
有同样的问题。已解决此问题。