问题
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.log
should be executed AFTER the execution of authenticationService.loginUser()
function.
回答1:
You need to return a promise using $q and act on that.
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));
});
};
回答2:
Try using $rootScope.$broadcast
in your service then listen for it in your controller:
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.
回答3:
If your application wait for external result, you should use $q for return a promise. If you are using angular-route
or ui-router
components, you can use resolve
param for this. Take a look ngRoute
documentation. In there has a example based in resolve param.
https://docs.angularjs.org/api/ngRoute/service/$route
回答4:
i think you have two options here
- as answered by comradburk, use promises:
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
回答5:
YOMS (Yet One More Solution):
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);
};
来源:https://stackoverflow.com/questions/23546593/angularjs-how-to-execute-a-controller-function-after-completion-of-ajax-call-in