我在.run方法中打开数据库db = $cordovaSQLite.openDB({name:"my.db"});
然后在.controller 里面执行了db.transaction(function (tx){},去查询数据库,
然后报错“TypeError: Cannot call method 'transaction' of null”,
这个问题是因为先执行了.controller后执行.run造成的吗?
我该怎么去解决这个问题呢?
------------补充---------------
.run写在了app.js中,.controller写在了controller.js中,并且,引用是,先引用了app.js,不知道这个信息是不是无关紧要
关键是你的db对象是共享的么?然后看下是不是打开数据库的时候出错了。
数据库共享是指的多个js都使用吗?
如果是这个意思,应该是共享的,我可以在controller.js里面访问db,
我刚接触angularjs,还不熟,不好意思
@一行代码闯天下: 这个和angular关系不大,主要看你的代码写法。你可以贴出你的run代码。和controller代码,包含db的部分。
@幻天芒:
app.js中.run方法:
.run(function($ionicPlatform, $cordovaSQLite) { $ionicPlatform.ready(function() { // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard // for form inputs) if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) { cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); cordova.plugins.Keyboard.disableScroll(true); } if (window.StatusBar) { // org.apache.cordova.statusbar required StatusBar.styleLightContent(); } db = $cordovaSQLite.openDB({name:"my.db"}); db.transaction(function(tx) { //tx.executeSql('DROP TABLE IF EXISTS people'); tx.executeSql('CREATE TABLE IF NOT EXISTS people (id integer primary key, Latitude text, Longitude text, datetimee text)'); tx.executeSql('CREATE TABLE IF NOT EXISTS users (id integer primary key, uname text, upassword text)'); /* demonstrate PRAGMA: db.executeSql("pragma table_info (people);", [], function(res) { console.log("PRAGMA res: " + JSON.stringify(res)); });*/ }); }); })
controller.js中.controller方法:
.controller('DashCtrl', function($scope,$location,db) { $scope.a = function () { db.transaction(function (tx){ tx.executeSql('SELECT uname, upassword FROM users ',[],function(tx,result) { if(result.rows.length!=0){ for(var i = 0; i < result.rows.length; i++){ console.log("SELECTED -> " + result.rows.item(i).uname + " * " + result.rows.item(i).upassword); } }else{ $location.path('/tab/login'); } }, function(e) { console.log("error "+e.message); }); }); } })
我在其他页面,有button触发一个方法,方法中才是才是db.transaction(function(tx) {}),这样不会出错,因为延时了方法的调用,触发button的时候db已经被打开了
//这个是button触发select方法,并不报错 $scope.select = function() { db.transaction(function (tx){ tx.executeSql('SELECT Latitude, Longitude, datetimee FROM people ',[],function(tx,result) { for(var i = 0; i < result.rows.length; i++){ console.log("SELECTED -> " + result.rows.item(i).Latitude + " * " + result.rows.item(i).Longitude+ " * " + result.rows.item(i).datetimee); } }, function(e) { console.log("error "+e.message); }); }); }
@一行代码闯天下: 看了代码,就已经很清晰了,你在run里面定义的db没有var,挂载到window对象上去了。你在controller中的db是依赖注入来的,两者并不是同一个对象,所以不能直接这样使用。可以写一个服务,来实现:
.constant('dbFactory', {}) .run(function(dbFactory){ dbFactory.db = $cordovaSQLite.openDB({name:"my.db"}); }); //然后在controller中使用: controller('xxx', function(dbFactory){ dbFactory.db.tran... });
@幻天芒:
噢,我的失误,db是有声明的,我把
var db = null;
写在了app.js的第一行了
@幻天芒:
在上文的代码中忘记贴出来了
@一行代码闯天下: 那也是没用的,如果你要用app.js顶部的那个db,那么你就不要在controller的function参数中写db,这里写db是会去查找依赖注入的。
@幻天芒:
.controller('DashCtrl', function($scope,$location,db) {})中的db是我后来加上的,刚刚贴代码的时候忘记删掉了,是我太疏忽大意了,
一开始是.controller('DashCtrl', function($scope,$location) {})提示“TypeError: Cannot call method 'transaction' of null”,
后来我在function中加入了db,错误就是“Error: [$injector:unpr] Unknown provider: dbProvider <- db <- DashCtrl”,实在不好意思哈
@一行代码闯天下:
这个是我遇到问题的.controller,我改回了原来的状态
.controller('DashCtrl', function($scope,$location) { /*$scope.yourname=null; if($scope.yourname=="admin"){ $location.path('/tab/login'); }*/ db.transaction(function (tx){ tx.executeSql('SELECT uname, upassword FROM users ',[],function(tx,result) { if(result.rows.length!=0){ for(var i = 0; i < result.rows.length; i++){ console.log("SELECTED -> " + result.rows.item(i).uname + " * " + result.rows.item(i).upassword); } }else{ $location.path('/tab/login'); } }, function(e) { console.log("error "+e.message); //$location.path('/tab/login'); }); }); })
@一行代码闯天下: 这意味着db是null或者undefined,你在run里面跟踪一下db的值嘛,特别是赋值之后,把db打出来看看。
@幻天芒:
可以了,我在controller里面加了个监听器,让数据库准备好后,再执行
.controller('DashCtrl', function($scope,$location) { document.addEventListener("deviceready",onDeviceReady,false); function onDeviceReady(){ db.transaction(function (tx){ tx.executeSql('SELECT uname, upassword FROM users ',[],function(tx,result) { if(result.rows.length!=0){ for(var i = 0; i < result.rows.length; i++){ console.log("SELECTED -> " + result.rows.item(i).uname + " * " + result.rows.item(i).upassword); } }else{ $location.path('/tab/login'); } }, function(e) { console.log("error "+e.message); }); }); } })
@一行代码闯天下: 原来你异步的问题,解决了就好。。