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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 01:04:31  来源:igfitidea点击:

AngularJS: How to execute a controller function AFTER completion of AJAX call in a service?

javascriptjqueryajaxangularjsxmlhttprequest

提问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-routeui-router组件,则可以resolve为此使用param。看一下ngRoute文档。在那里有一个基于解析参数的例子。

https://docs.angularjs.org/api/ngRoute/service/$route

https://docs.angularjs.org/api/ngRoute/service/$route

回答by panghal0

i think you have two options here

我想你在这里有两个选择

  1. as answered by comradburk, use promises:
  1. 正如 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;
});
};
  1. 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
  1. 使用解析,在控制器初始化之前在路由级别(...或状态级别,如果您使用 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);
    };