所以我似乎仍然无法正确理解承诺。我正在使用角度解析来阻止控制器在promise解决之前加载视图,但它不能按预期工作。我做错了什么?
这是我的服务
commonServicesModule.factory('helpdeskPriority', function($q, $timeout, getCommonList) {
var items;
return {
get: function(params) {
var defer = $q.defer();
$timeout(function() {
getCommonList.helpdesk.priority().success(function(result) {
console.log('waited for long tym ');
defer.resolve(result);
});
}, 0);
return defer.promise;
},
}
});
从控制器调用
helpdeskPriority.get().then(function(data) {
console.log(data);
});
我的优先功能
priority: function() {
return $http({
url: urlc.getListing.priority,
data: {
"params": JSON.stringify({})
},
method: 'POST',
});
},
答案 0 :(得分:1)
你没有得到的主要是.factory()
如何运作。它应该被赋予一个返回值的函数。它不需要自己的.get()
函数,Angular将为您{$get: <your factory function>}
创建一个提供者对象。
然后你需要意识到当你使用resolve时,依赖关系应该解析为promise。这意味着当注入器获得helpDeskPriority
依赖项的值时,它将获得一个promise作为值(因为它调用提供程序的$get
方法,这是您的工厂函数)。在运行控制器之前,解析机制将等待该承诺得到解决,helpDeskPriority
依赖性等于它所解决的值。
因此,请将工厂代码更改为:
commonServicesModule.factory('helpdeskPriority', function($q, $timeout, getCommonList) {
var items;
var defer = $q.defer();
$timeout(function() {
getCommonList.helpdesk.priority().success(function(result) {
console.log('waited for long tym ');
defer.resolve(result);
});
}, 0);
return defer.promise;
});
然后您的控制器变为:
function myController($scope, ..., helpDeskPriority) {
console.log(helpDeskPriority); // will already have the correct value
}
答案 1 :(得分:0)
将您的代码放入封闭可能会帮助您
commonServicesModule.factory('helpdeskPriority', function($q, $timeout, getCommonList) {
var items;
return {
get: function(params) {
var defer = $q.defer();
(function (deferred, list) {
$timeout(function() {
list.helpdesk.priority().success(function(result) {
console.log('waited for long tym ');
deferred.resolve(result);
});
}, 0);
})(defer, getCommonList);
return defer.promise;
},
}
});
答案 2 :(得分:-1)
您的代码是正确的。您只需要在绑定到模板的then()
回调中设置范围变量。 Angularjs将自动触发刷新:
helpdeskPriority.get().then(function(data) {
console.log(data);
@scope.myLazyLoadedData = data; // async initialization
});
此外:
以下jsfiddle http://jsfiddle.net/jeromerg/43F28/2/通过使用$http
+ $timeout
模拟$q
来电来重现您的示例。这个例子表明一切都很好!如果您仍然无法获得预期的行为,那么请您扩展jsfiddle示例并解释您的期望吗?所以,我们可以更好地了解正在发生的事情......
备注:
如果您想在$http
来电结束前阻止显示您的观看或部分观看,那么您可以将 ng-if="callFinished"
属性添加到您想要的元素中隐藏在你的模板中。并在控制器中的回调中设置范围标志callFinished,如下所示:
helpdeskPriority.get().then(function {
$scope.callFinished = true;
});
如果您希望在$http
调用结束之前保持上一个视图,然后更改为此视图,那么您应该从上一个视图中进行$http
调用并执行视图在那里更改$http.success()
回调。备选方案:您可以使用路由提供程序的resolve
属性,如下所述:Delaying AngularJS route change until model loaded to prevent flicker。但是,一旦调用了新视图的控制器功能,我就不会认为可以保留以前的视图。