AngularJS:如何在服务中完成AJAX调用后执行控制器功能?

时间:2014-05-08 15:49:34

标签: 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;
            });
        }
    });
};

这是我在控制器中的代码:

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

所以,我想要做的是,在完成AJAX调用后执行一些代码,其成功函数设置$ scope.currentUser的值,我可以用于某些条件逻辑(如重定向等) 成功函数正确设置了值,但console.log应在执行authenticationService.loginUser()函数后执行。

5 个答案:

答案 0 :(得分:12)

您需要使用$q返回承诺并对此采取行动。

例如在您的服务中:

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));
    });
};

答案 1 :(得分:2)

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

服务

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可能是一种更好的方式,但这并不是最好的方法。

答案 2 :(得分:0)

如果您的应用程序等待外部结果,您应该使用$ q来返回承诺。如果您使用的是angular-routeui-router组件,则可以使用resolve param。看一下ngRoute文档。在解决方案中有一个例子。

https://docs.angularjs.org/api/ngRoute/service/ $路线

答案 3 :(得分:0)

我认为你有两个选择

  1. 由comradburk回答,使用承诺:
  2. 服务中的

    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).then(function(user) {
        $scope.currentUser = user;
    });
    };
    
    1. 使用resolve,在控制器初始化之前在路由级别(...或状态级别,如果您使用ui-router)解析您的服务并将其作为依赖项插入 - 在用户身份验证等情况下非常有用,您不希望用户访问如果身份验证失败,则能够进一步导航。来自docs https://docs.angularjs.org/api/ngRoute/service/ $路线

答案 4 :(得分:0)

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);
    };