所以我似乎仍然没有正确理解promise。我使用角度解析来防止控制器在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',
});
},
您不太了解.factory()
是如何工作的。应该给它一个返回值的函数。它不需要自己的.get()
函数,Angular将使用{$get: <your factory function>}
为您创建一个提供程序对象。
然后你需要意识到,当你使用决心时,依赖应该转化为承诺。这意味着,当注入器获得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
}
将代码放入闭包中可能有助于
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;
},
}
});
您的代码是正确的。您只需要在绑定到模板的then()
回调中设置范围变量。Angularjs将自动触发刷新:
helpdeskPriority.get().then(function(data) {
console.log(data);
@scope.myLazyLoadedData = data; // async initialization
});
添加:
下面的jsfiddlehttp://jsfiddle.net/jeromerg/43F28/2/通过用$timeout
+$q
模拟$http
调用来重现您的示例。这个例子表明一切都很好!如果你仍然不能得到预期的行为,你能扩展jsfiddle的例子并解释你到底期望什么吗?这样,我们就可以更好地了解发生了什么…
备注:
如果要防止在$http
调用结束前显示视图或视图的一部分,则可以将ng-if="callFinished"
属性添加到要隐藏在模板中的元素中。并在位于控制器中的回调中设置作用域标志callFinished,如下所示:
helpdeskPriority.get().then(function {
$scope.callFinished = true;
});
如果您想在$http
调用结束之前一直停留在上一个视图中,然后更改到此视图,则应在上一视图中进行$http
调用,并在那里的$http.success()
回调中执行视图更改。备选方案:您可以使用路由提供程序的resolve
属性,如下所述:延迟AngularJS路由更改,直到加载模型,以防止闪烁。但是,一旦调用了新视图的控制器功能,我认为就不可能继续显示以前的视图。