____ INTRO
大家好,首先,三个澄清:
____ 目标
我想使用预先填充的数据库为iOS和Android开发应用。
例如,数据库包含 15.000条记录,每条记录由三个键值对组成( id , firstname 和名字)。
___ 我的内容
步骤:
ionic start myapp blank
cd myapp
ionic platform add ios
ionic platform add android
然后我创建了一个用于测试目的的sqlite数据库,名为 mydb.sqlite ,由一个表人组成,包含两个 id , firstname , lastname 记录。
我决定使用以下插件:https://github.com/Antair/Cordova-SQLitePlugin 那是因为它可以用cordova工具安装。
ionic plugin add https://github.com/Antair/Cordova-SQLitePlugin
(警告:我认为网站上的说明显示错误的引用 - “cordova plugin add https://github.com/brodysoft/Cordova-SQLitePlugin” - 这是指另一个插件。)
然后,按照插件网站上的说明,我将数据库复制到 myapp / www / db / ,以便现在可以在 myapp / www / db / mydb找到它。源码
我在默认 app.js 脚本之后修改了包含SQLite插件的 index.html :
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="SQLitePlugin.js"></script>
我还在 index.html 文件中写了一些代码行来显示一个按钮:
<ion-content ng-controller="MyCtrl">
<button class="button" ng-click="all()">All</button>
</ion-content>
最后我修改了 ./ js / app.js :
// Ionic Starter App
var db = null;
angular.module('starter', ['ionic' /* What goes here? */ ])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// some predefined code has been omitted
window.sqlitePlugin.importPrepopulatedDatabase({file: "mydb.sqlite", "importIfExists": true});
db = window.sqlitePlugin.openDatabase({name: "mydb.sqlite"});
}); // $ionicPlatform.ready
}) // .run
.controller('MyCtrl', function($scope){
$scope.all = function(){
var query = "SELECT * FROM people";
// I don't know how to proceed
}; // $scope.all
}); // .controller
___ 问题
我不知道如何在控制器部分继续查询所有记录(只是一个查询示例)并在console.log中显示结果。
我认为必须以某种方式完成以下代码:
angular.module('starter', ['ionic' /* What goes here? */ ])
还必须完成控制器部分内的代码:
$scope.all = function(){
var query = "SELECT * FROM people";
// I don't know how to proceed
}; // $scope.all
___ 最后感谢
提前感谢你们给予我的帮助。
答案 0 :(得分:2)
所以这个人的代码已经帮助我很多地封装了我的DAL。我强烈建议您逐字逐句地使用他的代码。
https://gist.github.com/jgoux/10738978
您会看到他有以下方法:
self.query = function(query, bindings) {
bindings = typeof bindings !== 'undefined' ? bindings : [];
var deferred = $q.defer();
self.db.transaction(function(transaction) {
transaction.executeSql(query, bindings, function(transaction, result) {
deferred.resolve(result);
}, function(transaction, error) {
deferred.reject(error);
});
});
return deferred.promise;
};
让我们稍微打破一下。查询函数采用查询字符串(查询参数)和可能的绑定列表?在类似&#34; SELECT * FROM A_TABLE WHERE ID =?&#34;的查询中。因为他的代码是一种服务,所以自我价值指向服务本身以用于所有未来的调用。该函数将对db执行一个事务,但它返回一个只有在db返回后才能实现的promise。
他的服务提供了第二个辅助函数:fetchAll。
self.fetchAll = function(result) {
var output = [];
for (var i = 0; i < result.rows.length; i++) {
output.push(result.rows.item(i));
}
return output;
};
fetchAll会将整个行读取到一个数组中。 fetchAll的结果参数是在查询函数的承诺履行中传递的结果变量。
如果您将其代码复制并粘贴到服务文件中,那么您现在拥有了一个真实的数据库服务。您可以将该服务包装在DAL中。这是我项目的一个例子。
.service('LocationService', function ($q, DB, Util) {
'use strict';
var self = this;
self.locations = [];
self.loadLocked = false;
self.pending = [];
self.findLocations = function () {
var d = $q.defer();
if (self.locations.length > 0) {
d.resolve(self.locations);
}
else if (self.locations.length === 0 && !self.loadLocked) {
self.loadLocked = true;
DB.query("SELECT * FROM locations WHERE kind = 'active'")
.then(function (resultSet) {
var locations = DB.fetchAll(resultSet);
self.locations.
push.apply(self.locations, locations);
self.loadLocked = false;
d.resolve(self.locations);
self.pending.forEach(function (d) {
d.resolve(self.locations);
});
}, Util.handleError);
} else {
self.pending.push(d);
}
return d.promise;
};
})
这个例子有点吵,因为它有一些&#34;线程&#34;代码,以确保相同的承诺被触发两次,它只对DB运行一次。一般的方法是显示DB.query返回一个promise。 &#34;然后&#34;在查询方法之后使用DB服务来获取所有数据并将其添加到我的本地内存空间中。所有这些都由self.findLocations协调,返回变量d.promise。
你的代表也是如此。控制器可以让您的DAL服务(如我的LocationService)由AngularJS注入其中。如果您正在使用AngularJS UI,则可以让它解析数据并将其传递到列表中。
最后,我对该代码的唯一问题是db应该来自这段代码。
var dbMaker = ($window.sqlitePlugin || $window);
原因是该插件在Apache Ripple中不起作用。由于该插件可以很好地镜像浏览器的Web SQL界面,因此这个简单的小改动将使Ripple能够运行您的Ionic应用程序,同时仍允许您在真实设备中使用SQLite。
我希望这会有所帮助。