热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Angular/Ionic和异步SQLite-确保数据工厂在返回之前初始化

如何解决《Angular/Ionic和异步SQLite-确保数据工厂在返回之前初始化》经验,为你挑选了1个好方法。

我正在使用Ionic编写PhoneGap/Cordova应用程序,并使用SQLite(使用ngCordova)进行持久存储.应用程序的核心是从SQLite数据库中检索的项目的滚动列表.

listController.js

.controller('ListCtrl', [
  '$scope',
  'dataFactory',
  function($scope, dataFactory) {

    var items = dataFactory.getAllItems().then(function(data){
      $scope.allItems = data;
    });

  }
]);

dataFactory.js

.factory('dataFactory', [function($window, $log, $q, $cordovaSQLite, dummyDataGenerator){    

  var db_;

  // ...lots of SQLite fun in here
  // cascading async callbacks to load the database and inject dummy data
  var openDB_ = function(){...};
  var createTable_ = function(){...};
  // etc

  var getAllItems = function(){

    var q = $q.defer();
    $cordovaSQLite.execute(db_, sqlSelectString, []).then(
      function(results) {
        $log.log("SQL SELECT successful");
        var i, len, allItems = [];
        for(i = 0, len = results.rows.length; i 

最初我是马上回到工厂.控制器getAllItems()在数据准备好之前运行了.该视图最初是空的,仅在一秒钟后返回路线时显示任何内容getAllItems()

所以我尝试通过添加一个factoryReady()函数来延迟工厂的返回,并且只有在所有内部数据库内容都准备就绪后才调用它

var factoryReady = function(){
  return {
    getAllItems: getAllItems
  };
};

现在有一个未定义的错误,因为整个工厂在第一次调用时不可用,而不是getAllItems()简单地空手而归.我可以看到SQL数据库在适当的时候正确写入,但Angular在完成之前会抛出异常.

我现在意识到这是可预测的,我已经阅读了AngularJS的帖子:使用异步数据初始化服务但不太了解如何实现排名靠前的答案(通过joakimbl)

在内部异步内容完成之前,暴露服务并确保控制器不会调用它的最佳方法是什么?我是否需要将ENTIRE服务作为承诺而不仅仅是结果返回getAllItems?我有一个去,但现在我很困惑.谢谢.

编辑

resolve在加载视图http://blog.brunoscopelliti.com/show-route-only-after-all-promises-are-resolved时,我也考虑过使用ui-router ,但这并没有解决内部的准备问题. SQL数据/工厂.如果我返回getAllCases方法然后它仍然立即被调用,SQL数据库中没有任何内容,SQL查询返回一个空结果集,promise解析并呈现视图.



1> drjimmie1976..:

管理以使其最终运作.在这里发布这个问题给其他人.

dataFactory.js

使用dataFactory.js中的异步SQL调用重写所有私有方法以返回promise

创建了一个公共initDB方法,该方法链接了对私有方法的调用(例如openDB>> dropTable_>> createTable_etc).还退了一张诺(空)

返回initDBgetAllItems()从工厂直接

.factory('dataFactory', [function($window, $log, $q, $cordovaSQLite, dummyDataGenerator){    

  var db_;

  // private methods - all return promises

  var openDB_ = function(dbName){

    var q = $q.defer();
    // ...call async SQL methods
    return q.promise;
  };

  var createTable_ = function(){
    var q = $q.defer();
    // ...call async SQL methods
    return q.promise;               
  };

  // ...etc

  // public methods

  var initDB = function(){

    var q = $q.defer();
    // successively call private methods, chaining to next with .then()
    openDB_("myDB").then(function(db){
      var schema = "...SQL schema here..."
      dropTable_(db, "FirstTable", schema).then(function(tableName){
        // ...etc
        // when all done, resolve the promise
        q.resolve();
      })
    })
    return q.promise;
  }

  var getAllItems = function(){

    var q = $q.defer();
    // ...call async SQL methods
    return q.promise;
  };

  return {
    initDB: initDB,
    getAllItems: getAllItems 
  };

]}); // <-- factory

app.js

使用ui-routerresolve能力

我以前的尝试没有正确地注入承诺

添加resolve到顶级抽象状态以触发调用initDB

将承诺注入initDB到子状态的resolve对象中

将resolve对象注入控制器

// APP ROUTING(使用ui-router).config(function($ stateProvider,$ urlRouterProvider){

$stateProvider

  // top-level abstract state that houses Ionic side menu & nav
  .state('app', {
    url: '/app',
    abstract: true,
    templateUrl: "templates/sideMenu.html",
    resolve: {
      dbReady: function($log, dataFactory){
        // (1) init the DB
        return dataFactory.initDB().then(function(){
          $log.log("initDB promise resolved");
      });
    }
  }
})

// the following states are all child states of app

.state('app.items', {
  url: "/items",
  views: {
    menuContent: {
      templateUrl: "templates/gbCaseList.html",
      // (3) now we can inject the items promise into our controller
      controller: function($scope, $log, items){
        // (4) uses resolved items variable injected by ui-router
        $scope.allItems = items;
      }
    }
  },
  resolve: {
    // (2) note that we MUST inject the dbReady promise, if we don't this will instantiate immediately
    items: function(dbReady, $log, dataFactory){
      // the following call returns a promise
      return dataFactory.getItems();
    }
  }
})

一切正常.非常感谢这篇文章,只有在AngularJS中完成初始化后才能清除我对ui-router 运行控制器的使用


推荐阅读
author-avatar
mobiledu2502855757
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有