javascript AngularJS:如何在服务中完成 AJAX 调用后执行控制器函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23546593/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AngularJS: How to execute a controller function AFTER completion of AJAX call in a service?
提问by Vishwajeet Vatharkar
Here's my code in the service.
这是我在服务中的代码。
this.loginUser = function(checkUser) {
Parse.User.logIn(checkUser.username, checkUser.password, {
success: function(user) {
$rootScope.$apply(function (){
$rootScope.currentUser = user;
});
}
});
};
Here's my code in the controller:
这是我在控制器中的代码:
$scope.logIn = function(){
authenticationService.loginUser($scope.checkUser);
console.log($scope.currentUser)
};
So, what I want to do is, execute some code AFTER the completion of AJAX call, whose success function sets the value of $scope.currentUser, which, I can use for some conditional logic (like redirecting etc)
The success function is correctly setting the value, but the console.logshould be executed AFTER the execution of authenticationService.loginUser()function.
所以,我想要做的是,在 AJAX 调用完成后执行一些代码,其成功函数设置 $scope.currentUser 的值,我可以将其用于一些条件逻辑(如重定向等)成功函数是正确的设置值,但console.log应在执行authenticationService.loginUser()函数后执行。
回答by andrew.burk
You need to return a promise using $qand act on that.
您需要使用$q返回一个承诺并采取行动。
For instance in your service:
例如在您的服务中:
this.loginUser = function(checkUser) {
var deferred = $q.defer();
Parse.User.logIn(checkUser.username, checkUser.password, {
success: function(user) {
$rootScope.$apply(function (){
$rootScope.currentUser = user;
});
deferred.resolve();
}
});
return deferred.promise;
};
Then in your controller act on the success:
然后在您的控制器中操作成功:
$scope.logIn = function(){
authenticationService.loginUser($scope.checkUser).then(function() {
console.log($rootScope.currentUser));
});
};
回答by m.e.conroy
Try using $rootScope.$broadcastin your service then listen for it in your controller:
尝试$rootScope.$broadcast在您的服务中使用,然后在您的控制器中监听它:
Service
服务
Parse.User.logIn(checkUser.username, checkUser.password, {
success: function(user) {
$rootScope.$apply(function (){
$rootScope.currentUser = user;
$rootScope.$broadcast('user.online');
});
}
});
Controller
控制器
$scope.$on('user.online',function(){
[ DO STUFF HERE ]
});
This isn't the best way to do this though @comradburk's use of $q is probably a better way.
尽管@comradburk 使用 $q 可能是更好的方法,但这并不是最好的方法。
回答by Wilson Mendes
If your application wait for external result, you should use $q for return a promise. If you are using angular-routeor ui-routercomponents, you can use resolveparam for this. Take a look ngRoutedocumentation. In there has a example based in resolve param.
如果您的应用程序等待外部结果,您应该使用 $q 来返回一个承诺。如果您正在使用angular-route或ui-router组件,则可以resolve为此使用param。看一下ngRoute文档。在那里有一个基于解析参数的例子。
回答by panghal0
i think you have two options here
我想你在这里有两个选择
- as answered by comradburk, use promises:
- 正如 comradburk 所回答的,使用承诺:
in Services:
在服务:
this.loginUser = function(checkUser) {
var deferred = $q.defer();
Parse.User.logIn(checkUser.username, checkUser.password, {
success: function(user) {
deferred.resolve(user);
}
});
return deferred.promise;
};
};
in controller:
在控制器中:
$scope.logIn = function(){
authenticationService.loginUser($scope.checkUser).then(function(user) {
$scope.currentUser = user;
});
};
- using resolve, resolve your service at route level (...or state level in case you are using ui-router) before controller initialization and insert it as a dependency - helpful in scenarios like user authentication where you dont want user to be able to navigate further if authentication fails. from docs https://docs.angularjs.org/api/ngRoute/service/$route
- 使用解析,在控制器初始化之前在路由级别(...或状态级别,如果您使用 ui-router)解析您的服务并将其作为依赖项插入 - 在用户身份验证等场景中很有帮助,您不希望用户能够如果身份验证失败,则进一步导航。来自文档 https://docs.angularjs.org/api/ngRoute/service/$route
回答by Dementic
YOMS (Yet One More Solution):
YOMS(又一个解决方案):
this.loginUser = function(checkUser, onSuccess) {
Parse.User.logIn(checkUser.username, checkUser.password, {
success: function(user) {
$rootScope.$apply(function() {
$rootScope.currentUser = user;
if (typeof onSuccess == 'function') onSuccess(user); // optionally pass data back
});
}
});
};
$scope.logIn = function(user, function(returnedUser) {
// console.log(returnedUser); // Optional, The returned user
console.log($scope.currentUser)
}) {
authenticationService.loginUser($scope.checkUser);
};

