根据请求更新了HTTP和初始代码/请查看帖子底部:
我最近在AngularJS的学习曲线上发布了几个问题,SO社区也很精彩。我以前编程并且最近开始编写我自己的离子/ Angular JS应用程序时,我一直是传统的C程序员。在将自定义函数转换为promise时,我正在努力处理传统异步调用的promise版本。我不认为我真的理解,我发现各种各样的例子非常人为。我很感激一些帮助。我有一些代码无效,我有一些概念性的问题:
让我们来看看这个简单的功能:
angular.module('zmApp.controllers').service('ZMDataModel', function() { return { getMonitors: function () { return monitors; } }
getMonitors是一个简单的函数,它基本上返回一组监视器。但这就是问题:当应用程序首次启动时,我会调用一个http工厂来执行http get,然后填充此监视器列表。此http工厂与此服务不同,但在此服务中调用setMonitor方法来填充数组。当数组被填充时,一个名为' monitorsLoaded'的变量被称为设置为1.当此变量设置为1时,我确定已加载监视器。
现在,我有一个名为" MontageCtrl"的控制器的视图。我想在显示视图之前等待监视器加载。在之前的帖子中,有人建议我使用路由解析,但我必须先将我的getMonitors转换为promise。所以这就是我所做的:
angular.module('zmApp.controllers').service('ZMDataModel', function($q) {
getMonitors: function () {
var _deferred = $q.defer();
if (monitorsLoaded!=0)
{
console.log ("**** RETURNING MONITORS *****");
_deferred.resolve(monitors);
}
console.log ("*** RETURNING PROMISE ***");
return _deferred.promise;
},
接下来,在app.js中我按如下方式连接路线:
.state('app.montage', {
data: {requireLogin:false},
resolve: {
message: function(ZMDataModel)
{
console.log ("Inside app.montage resolve");
return ZMDataModel.getMonitors();
}
},

最后我修改了我的控制器以获取承诺:
angular.module('zmApp.controllers').controller('zmApp.MontageCtrl', function($scope,$rootScope, ZMHttpFactory, ZMDataModel,message) {
//var monsize =3;
console.log ("********* Inside Montage Ctrl");

似乎基于日志,我从不进入蒙太奇控制台。路由解析似乎正在等待,而我的日志显示一段时间后,monitorLoaded被设置为1。
我有几个概念性问题:
a)在我按照例子制作的函数getMonitors中,为什么人们返回_deferred.promise但只分配_deferred.resolve? (也就是为什么不回来?)。它会自动返回吗?
b)我注意到如果我将var _deferred定义移动到我的服务并且移出了它的子函数,它确实有效,但是具有相同路由依赖性的下一个视图没有。我很困惑。
c)最后,我准备在某个地方,当涉及到路由解析时,服务和工厂之间存在区别,因为服务仅实例化一次。我也很困惑,因为在人们使用的一些路由解析示例中,我正在使用.state。 在这个阶段,我深陷于自己的困惑之中。有人可以帮忙澄清一下吗?所有我真正想要的是等待各种观点,直到monitorLoaded为1.我想通过路由解析和承诺来做到这一点,所以我一劳永逸地接受了承诺。
已添加:以下是HTTP工厂代码以及在应用首次启动时调用此代码的app.run代码。仅供参考,http工厂运行良好 - 当我制作ZMDataModel时出现的问题 - 我希望这是所有控制器使用的中央数据存储库 - 因此他们不必每次都调用HTTP Factory来访问数据,我可以需要调用HTTP工厂时控制
angular.module('zmApp.controllers').factory('ZMHttpFactory', ['$http', '$rootScope','$ionicLoading', '$ionicPopup','$timeout','ZMDataModel',
function($http, $rootScope, $ionicLoading, $ionicPopup, $timeout,ZMDataModel) {
return {
getMonitors: function() {
var monitors = [];
var apiurl = ZMDataModel.getLogin().apiurl;
var myurl = apiurl+"/monitors.json";
return $http({
url: myurl,
method: 'get'
}) //http
.then(function(response) {
var data = response.data;
//console.log("****YAY" + JSON.stringify(data));
// $rootScope.$broadcast ('handleZoneMinderMonitorsUpdate',monitors);
$ionicLoading.hide();
ZMDataModel.setMonitors(data.monitors);
ZMDataModel.setMonitorsLoaded(1);
//monitors = data.monitors;
return ZMDataModel.getMonitors();
},
function (result)
{
console.log ("**** Error in HTTP");
$ionicLoading.hide();
ZMDataModel.setMonitorsLoaded(1);
//$ionicPopup.alert ({title: "Error", template:"Error retrieving Monitors. \nPlease check if your Settings are correct. "});
return ZMDataModel.getMonitors();
}
); //then
}, //getMonitors

以下是app.run中首先调用此代码的代码:
.run(function($ionicPlatform, $ionicPopup, $rootScope, $state,ZMDataModel, ZMHttpFactory)
{
ZMDataModel.init();
var loginData = ZMDataModel.getLogin();
if ( loginData.username && loginData.password && loginData.url && loginData.apiurl)
{
console.log ("VALID CREDENTIALS. Grabbing Monitors");
// this calls http factory getMonitors that eventually populated the ZMDataModel
// monitors array and sets monitorsLoaded to 1
ZMHttpFactory.getMonitors();
}
}

答案 0 :(得分:0)
我终于解决了所有问题。我最初的尝试有各种各样的问题。我最终解决的解决方案是Am I returning this promise correctly?
学习:
a)将HTTP进入工厂分离,将数据模型分离到另一个服务中,不必要地使生活变得复杂。但这种分离不是问题。事实上,承诺在上面编码的方式,在第一次运行时,如果monitorsLoaded为0,它将简单地返回延迟的承诺,并且没有“.success”或类似的构造让我再次进入解析代码块。
b)让我在循环中跑来跑去的最大的事情就是推迟或拒绝只是设置状态。返回总是必须是承诺 - 它会返回你设置的状态。我假设返回d.promise总是意味着返回“正在进行中”。