【问题标题】:IndexedDB as Angular serviceIndexedDB 作为 Angular 服务
【发布时间】:2014-04-12 01:04:09
【问题描述】:

我在 Angular 服务中打开一个 IndexedDB:

MyApp.factory '$database', ->
  database = null

  request = indexedDB.open 'myApp', '1'

  request.onerror = (e) ->
    console.log e

  request.onsuccess = (e) ->
    database = e.target.result

该服务还有一个方法可以返回某个集合中的所有记录:

all: (collection, resultsCallback) ->
  request = database.transaction... (omitted for brevity)

这里的问题是,当我的页面加载时,控制器将从数据库中获取所有记录。但是有可能IndexedDB的成功回调还没有被调用,所以数据库是null

查看https://github.com/webcss/angular-indexedDB/blob/master/src/indexeddb.js 的代码,似乎每次查询都会再次打开数据库,并在成功回调中执行查询。

我不确定这是否完全合适。虽然这可以解决我遇到的问题,但这不会留下很多与数据库的悬空连接吗?每次需要执行查询时都可以打开连接吗?

如果不是,那么 Angular 中的合适解决方案是什么?

【问题讨论】:

    标签: javascript html angularjs coffeescript


    【解决方案1】:

    我在为 IndexedDB 搜索 AngularJS Wrapper 时遇到了您的问题。我正在查看代码,当然,自从您在几个月前查看它以来,它可能已经发生了变化。

    我不相信您引用的包装器会在每次连续调用时打开和关闭数据库。您可能会注意到每个数据库访问都会调用函数this.internalObjectStore()

    internalObjectStore: function(storeName, mode) {
        var me = this;
        return dbPromise().then(function(db){
            me.transaction = db.transaction([storeName], mode || READONLY);
            me.transaction.oncomplete = module.onTransactionComplete;
            me.transaction.onabort = module.onTransactionAbort;
            me.onerror = module.onTransactionError;
    
            return me.transaction.objectStore(storeName);
         });
    },
    

    dbPromise() 的调用可以打开数据库,或者如果它已经打开,它只是返回要打开的数据库的承诺。如果数据库已经打开,则 Promise 已经解析,因此会立即调用该函数。这只是一种确保所有请求等到数据库最初打开的方法。

    现在更多关于您的问题

    我相信您正在经历在 AngularJS 上下文之外调用您的回调函数。类似于$apply() 可以将您的代码放回 Angular,您需要一种方法来告诉 AngularJS 发生在 request.onsuccess()request.onerror() 中的代码。您链接到的包装器使用来自 $q 的 AngularJS 承诺,它将您的代码放回 AngularJS 上下文中。

    我不擅长这种语法,所以我将恢复到标准 JavaScript。这样做是通过数据库承诺运行所有 API 函数。这将确保所有请求都将在数据库打开后发生。同样重要的是要注意解决承诺的 $apply 调用。这使上下文重新回到角度。

    MyApp.factory('$database', function($q, $rootScope){
      var database = null,
          deferred = $q.defer(),
          dbPromise = deferred.promise,
          request = indexedDB.open('myApp', '1');
    
      request.onerror = function(e){
          console.log(e);
          $rootScope.$apply(function(){                  
              deferred.reject(e);
          });
      }
    
      request.onsuccess = function(e){
          $rootScope.$apply(function(){                  
              database = e.target.result;
              deferred.resolve();
          });
      }
    
    
      var api = {
          all: function(){ dbPromise.then(function(){...}); },
      }
    
      return api;
    
    });
    

    【讨论】:

      猜你喜欢
      • 2017-11-14
      • 2017-07-03
      • 1970-01-01
      • 2013-12-19
      • 1970-01-01
      • 2020-03-30
      • 1970-01-01
      • 2017-11-17
      • 2023-03-11
      相关资源
      最近更新 更多