我正在用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 < len; i++) {
allItems.push(results.rows.item(i));
}
q.resolve(allItems);
},
function (err) {
q.reject(err);
}
);
return q.promise;
};
return { getAllItems: getAllItems };
]}); // <-- factory
最初我是马上回到工厂 . 控制器在数据准备好之前运行 getAllItems()
. 该视图最初为空,仅显示返回路径后的任何内容 getAllItems()
所以我尝试通过添加一个factoryReady()函数来延迟工厂的返回,并且只有在所有内部数据库内容都准备就绪后才调用它
var factoryReady = function(){
return {
getAllItems: getAllItems
};
};
现在有一个未定义的错误,因为整个工厂在第一次调用时不可用,而不是 getAllItems()
只是空手而归 . 我可以看到SQL数据库在适当的时候正确写入,但Angular在完成之前抛出异常 .
我现在意识到这是可以预测的,我已经阅读了帖子AngularJS : Initialize service with asynchronous data但是不太明白如何实现排名靠前的答案(由joakimbl提供)
在内部异步内容完成之前,控制器没有调用什么's the best way to expose the service and ensure it'?我是否需要将ENTIRE服务作为承诺而不仅仅是 getAllItems
的结果返回?我有一个去,但现在我很困惑 . 谢谢 .
编辑
我在加载视图http://blog.brunoscopelliti.com/show-route-only-after-all-promises-are-resolved但是没有修复SQL数据/工厂的内部准备情况时've also looked into using ui-router' s resolve
. 如果我返回 getAllCases
方法然后它仍然立即被调用,SQL数据库中没有任何内容,SQL查询返回一个空结果集,promise解析并呈现视图 .
1 回答
管理以使其最终运作 . 在这里发布这个问题给其他人 .
dataFactory.js
使用 dataFactory.js 中的异步SQL调用重写了所有私有方法以返回promises
创建了一个公共initDB方法,该方法链接了对私有方法的调用(例如
openDB
>>dropTable_
>>createTable_
等) . 还退了一张诺言(空)立即从工厂返回
initDB
和getAllItems()
app.js
使用了_254770_ ui-router 的能力
我以前的尝试没有正确地注入承诺
将
resolve
添加到顶级抽象状态以触发对initDB
的调用将
initDB
的承诺注入子状态的resolve
对象将解析对象注入控制器
// APP ROUTING(使用ui-router).config(function($ stateProvider,$ urlRouterProvider){
一切正常 . 非常感谢这篇帖子清理我使用的ui-router Run controllers only after initialization is complete in AngularJS