我的控制器中有很多服务调用,从这些服务获取数据后,我想在指令中触发一个函数。
//这是我的控制器
function myctrl(){
Serv.query({"type":"PageDetails"}, request.pageDetails, function(data) { if(data.status=="SUCCESS") { $scope.display.pageDetails = data.list; Serv.query({"type":"userDetails"}, request.userDetails, function(data) { if(data.status=="SUCCESS") { $scope.display.userDetails = data.list; $scope.loaded = true; } }); } });
}
//这是我的服务工厂
app.factory('KYC',function($resource) { return $resource('serviceUrl/:type',{}, { query: {method: 'POST', isArray: false}, get: {method: 'GET', isArray: false} }); });
//这是我的指示
app.directive('showSlowly',function() { return { restrict: 'EA', link: function(scope, element, attrs){ scope.$watch('loaded', function(isLoaded) { if(isLoaded) { setTimeout(function() { $(element).animate({height:"140px"}, 'slow', function(){ $(element).css({overflow:"visible"}); }); }, 300); } }); } }; });
这不是最好的方法。 任何人都可以帮助用$ q完成这项工作。提前致谢。
答案 0 :(得分:1)
在您的示例中,似乎您希望在加载数据后执行代码。您的代码似乎应该按原样运行,但如果您想尝试使用$q
的不同代码,那么您可以使$scope.loaded
成为承诺。您的其他代码可以引用该promise,并将其传递给promise,以便在解析promise时运行(这与设置$watch
以在值更改时运行方法非常相似)
控制器代码:
与您现在拥有的非常相似...首先,确保您在控制器/应用中注入$q
。然后,创建一个承诺并将其存储在loaded
:
var loadedDefer = $q.defer();
$scope.loaded = loadedDefer.promise;
然后在查询成功之内,而不是设置loaded = true
,请使用
loadedDefer.resolve(true);
(您可以将任何对象传递给resolve方法,但我选择true
,因为这是您当前代码已经在寻找的内容。)
指令代码:
您可以直接使用承诺,而不是使用$watch
。
$scope.loaded.then( function(isLoaded){...} );
此设置与您已经完成的工作非常相似,但熟悉$ q并在适当的时候使用它是很好的。
答案 1 :(得分:0)
最后,我可以用$ q.all()来实现这个目标。
//this is my controller code
function myctrl($q, $scope) {
var deferredObjs = {
"d1":$q.defer,
"d2":$q.defer
}
$scope.promises = { "p1":d1.promise,"p2":d2.promise};
Serv.query({"type":"PageDetails"}, request.pageDetails, function(data) {
if(data.status=="SUCCESS") {
$scope.display.pageDetails = data.list;
$scope.apply(function() {
deferredObjs.d1.resolve();
}
}else {
$scope.apply(function() {
deferredObjs.d1.reject();
}
}
});
Serv.query({"type":"userDetails"}, request.userDetails, function(data) {
if(data.status=="SUCCESS") {
$scope.display.userDetails = data.list;
$scope.apply(function() {
deferredObjs.d2.resolve();
}
}else {
$scope.apply(function() {
deferredObjs.d2.reject();
}
}
});
}
// this is my directive
app.directive('showSlowly',function($q) {
return {
restrict: 'EA',
link: function(scope, element, attrs){
$q.all([scope.promises.p1.then(function(){}), scope.promises.p2.then(function(){}]).then(function() {
setTimeout(function() {
$(element).animate({height:"140px"}, 'slow', function(){
$(element).css({overflow:"visible"});
});
}, 300);
});
}
};
});