我正在 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)
这里的问题是当我的页面加载时, Controller 将从数据库中获取所有记录。但是,可能尚未调用 IndexedDB 的成功回调,因此数据库为 null
。
查看 https://github.com/webcss/angular-indexedDB/blob/master/src/indexeddb.js 处的代码似乎每次查询都会再次打开数据库,并在成功回调中执行查询。
我不确定这是否完全合适。虽然这可以解决我遇到的问题,但这不会留下很多与数据库的悬空连接吗?每次需要执行查询时打开一个连接是否可以?
如果不是,Angular 中合适的解决方案是什么?
最佳答案
我在为 IndexedDB 搜索 AngularJS 包装器时遇到了您的问题。我正在查看代码,自从您几个月前查看代码以来,这些代码当然可能发生了变化。
我不相信您引用的包装器会在每次连续调用时打开和关闭数据库。您可能会注意到每个数据库访问都会调用函数 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 。如果数据库已经打开,则 promise 已经解决,因此会立即调用该函数。这只是确保所有请求等到数据库最初打开的一种方法。
现在更多关于你的问题
我相信您遇到了在 AngularJS 上下文之外调用回调函数的情况。类似于 $apply()
可以将您的代码放回 Angular ,您需要一种方法来告诉 AngularJS 关于 request.onsuccess()
和 request.onerror()
。您链接到的包装器使用 $q
中的 AngularJS promise ,这会将您的代码放回到 AngularJS 上下文中。
我不擅长这种语法,所以我要恢复到标准 JavaScript。它所做的是通过数据库 promise 运行所有 API 函数。这将确保所有请求都在数据库打开后发生。同样重要的是要注意 promise 已解决的 $apply 调用。这使上下文恢复了 Angular 。
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;
});
关于javascript - IndexedDB 作为 Angular 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22274557/