Javascript AngularJS:在服务中完成AJAX调用后,如何执行控制器函数?

Javascript AngularJS:在服务中完成AJAX调用后,如何执行控制器函数?,javascript,jquery,ajax,angularjs,xmlhttprequest,Javascript,Jquery,Ajax,Angularjs,Xmlhttprequest,这是我在服务中的代码 this.loginUser = function(checkUser) { Parse.User.logIn(checkUser.username, checkUser.password, { success: function(user) { $rootScope.$apply(function (){ $rootScope.currentUser = user; }

这是我在服务中的代码

this.loginUser = function(checkUser) {
    Parse.User.logIn(checkUser.username, checkUser.password, {
        success: function(user) {
            $rootScope.$apply(function (){
                $rootScope.currentUser = user;
            });
        }
    });
};
以下是我在控制器中的代码:

$scope.logIn = function(){
    authenticationService.loginUser($scope.checkUser);
        console.log($scope.currentUser)
};
$scope.logIn = function(){
authenticationService.loginUser($scope.checkUser).then(function(user) {
    $scope.currentUser = user;
});
};
所以,我想做的是,在AJAX调用完成后执行一些代码,它的success函数设置$scope.currentUser的值,我可以将其用于一些条件逻辑(如重定向等)
success函数正确设置了值,但是
console.log
应该在执行
authenticationService.loginUser()
函数后执行。

您需要使用返回承诺并执行该承诺

例如,在您的服务中:

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;
};
然后在控制器中,对成功采取行动:

$scope.logIn = function(){
    authenticationService.loginUser($scope.checkUser).then(function() {
        console.log($rootScope.currentUser));
    });
};

尝试在您的服务中使用
$rootScope.$broadcast
,然后在控制器中收听:

$scope.logIn = function(){
    authenticationService.loginUser($scope.checkUser);
        console.log($scope.currentUser)
};
$scope.logIn = function(){
authenticationService.loginUser($scope.checkUser).then(function(user) {
    $scope.currentUser = user;
});
};
服务

Parse.User.logIn(checkUser.username, checkUser.password, {
    success: function(user) {
        $rootScope.$apply(function (){
            $rootScope.currentUser = user;
            $rootScope.$broadcast('user.online');
        });
    }
});
控制器

$scope.$on('user.online',function(){
    [ DO STUFF HERE ]
});

虽然@comradburk使用$q可能是更好的方法,但这并不是最好的方法。

如果应用程序等待外部结果,则应使用$q返回承诺。如果您使用的是
angular route
ui router
组件,则可以使用
resolve
param进行此操作。查看
ngRoute
文档。中有一个基于resolve param的示例


$route

我想您有两种选择

  • 正如comradburk所回答的,使用承诺:
  • 在职:

    this.loginUser = function(checkUser) {
    var deferred = $q.defer();
    Parse.User.logIn(checkUser.username, checkUser.password, {
        success: function(user) {
            deferred.resolve(user);
        }
    });
    return deferred.promise;
    
    })

    在控制器中:

    $scope.logIn = function(){
        authenticationService.loginUser($scope.checkUser);
            console.log($scope.currentUser)
    };
    
    $scope.logIn = function(){
    authenticationService.loginUser($scope.checkUser).then(function(user) {
        $scope.currentUser = user;
    });
    };
    
  • 使用resolve,在控制器初始化之前在路由级别(…或状态级别,如果您使用的是ui路由器)解析您的服务,并将其作为依赖项插入-在用户身份验证之类的场景中很有用,在这种场景中,如果身份验证失败,您不希望用户能够进一步导航。来自文档 $route
  • YOMS(还有一个解决方案):


    我试过这个。但是我的
    console.log($scope.currentUser)
    仍然没有记录currentUser的新值(由ajax服务调用的成功函数设置)。我进行了编辑。服务正在$rootScope上设置当前用户,控制器正在查看$scope.currentUser,并且应该是$rootScope.currentUser.Yes!成功了!谢谢:-)尽管有人建议我使用$rootScope是不好的做法。我现在正试图重构我的代码,以便从我的服务中删除$rootScope的使用。:-)要了解更多“angularjs”的方法,请参阅@comradburk答案