使用Antair Cordova SQLitePlugin的离子预填充数据库[帮助请求]

时间:2014-12-01 21:39:34

标签: ios sqlite cordova ionic

____ INTRO

大家好,首先,三个澄清:

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

    我想使用预先填充的数据库为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
    

    ___ 最后感谢

    提前感谢你们给予我的帮助。

1 个答案:

答案 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。

我希望这会有所帮助。

相关问题