3

____介绍

大家好,首先澄清三点:

  1. 我的英语不好,所以请您原谅我的错误,
  2. 我是新手,不准确的地方见谅
  3. 我之前搜索并尝试了我在互联网上找到的解决方案,但我仍然无法解决嵌入预填充数据库的问题。

____目标

我想为 iOS 和 Android 开发一个带有预填充数据库的应用程序。

例如,数据库包含15.000 条记录,每条记录由三个键值对(idfirstnamelastname)组成。

___我做了什么

脚步:

ionic start myapp blank
cd myapp
ionic platform add ios
ionic platform add android

然后我创建了一个用于测试目的的 sqlite 数据库,名为mydb.sqlite,由一个包含两个 idfirstnamelastname记录的表people组成。

我决定使用以下插件: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.sqlite 找到它

我在默认app.js脚本之后修改了index.html ,包括 SQLite 插件:

<!-- 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

___最后感谢

预先感谢您对我的帮助。

4

1 回答 1

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;
};

让我们分解一下。查询函数接受一个查询字符串(查询参数)和一个可能的绑定列表?在类似“SELECT * FROM A_TABLE WHERE ID = ?”的查询中。因为他的代码是服务,所以 self 值指向服务本身以供将来所有调用使用。该函数将对数据库执行事务,但它返回一个只有在数据库返回时才会履行的承诺。

他的服务提供了第二个辅助函数: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;
        };
})

这个例子有点吵,因为它有一些“线程”代码来确保相同的承诺是否被触发两次,它只对数据库运行一次。一般的要点是表明 DB.query 返回一个承诺。查询方法后面的“then”使用数据库服务来获取所有数据并将其添加到我的本地内存空间中。所有这些都由返回变量 d.promise 的 self.findLocations 协调。

你的也会同样代表。控制器可以让你的 DAL 服务,比如我的 LocationService,由 AngularJS 注入。如果您使用的是 AngularJS UI,您可以让它解析数据并将其传递到列表中。

最后,我对这家伙的代码唯一的问题是数据库应该来自这个代码。

var dbMaker = ($window.sqlitePlugin || $window);

原因是该插件在 Apache Ripple 中不起作用。由于该插件可以很好地镜像浏览器的 Web SQL 界面,因此这个简单的小改动将使 Ripple 能够运行您的 Ionic 应用程序,同时仍然允许您在真实设备中工作您的 SQLite。

我希望这有帮助。

于 2014-12-02T03:25:39.070 回答