在调用服务中的方法之前,如何异步执行某些代码?

时间:2014-02-13 11:55:09

标签: angularjs

我在初始化服务之前执行某些任务时遇到了一些问题,并且使用了它的方法。一些背景:

我正在制作一个使用REST与2个不同的后端系统进行通信的应用程序(原因是如果我们的客户端将来升级它仍然可以工作)。对于相同的REST调用,这些后端系统的路径略有不同。

要知道使用哪个调用我认为解决方案可能是调用一个存在于一个测试端点而不是另一个测试端点的测试端点,并根据收到的响应代码设置一个变量,该变量是URL的开头。例如/ REST /服务/ StartpointService /.

所有REST调用都在一个工厂中,我尝试过这样的事情:

angular.module('myApp.services', [])
.factory('myServices', [
    '$http',
    '$q',
    function($http, $q) {

        //test function, if success we are using 1 backend, if fails, we use the other
        var loginTest = function() {

            var deferred = $q.defer();

            $http( {

                method: 'POST',
                url: '/um/login?um_no_redirect=true'

            })
            .success(function(data, status, headers, config) {

                deferred.resolve(status);

            })
            .error(function(data, status, headers, config) {

                deferred.reject(status);

            });
            return deferred.promise;

        };


        var url;

        loginTest()
        .then( function(response) { //if backend1

            if(responseCode === 200) {
                url = '/rest/services/etc/etc' //set the URL
            }

        },
        function(errorCode) {   //If backend2


            if(errorCode === 404) {

                url = '/LCConnector/rest/services/etc/etc';

            }

        });



        var service = {

            realCall : function() {

                                    //use 'url' variable in the $http call

                            }
                    }

                    return service;

           }]);

显然,当loginTest是异步的时,服务会被注入我的控制器并在设置url之前被调用。

我已经考虑过在首次初始化应用程序时运行配置或运行块,但无法理解如何获取变量。

如果我能提供更多详情,请告诉我!

此致

奥吉尔

2 个答案:

答案 0 :(得分:2)

如果在初始化应用程序之前需要进行此检查,则可以在Ajax调用后手动bootstrap应用程序。在fail()done()回拨内,您可以更改模块配置以反映您需要的网址。从那里,您可以轻松地将config注入任何需要此URL的服务。

example on jsfiddle

<div ng-controller="MyCtrl">{{url}}</div>


//if you chanée this url to /echo/fail and url will now be url1
var urlToCheck = '/echo/json/';

var myApp = angular.module('myApp', []);

myApp.controller("MyCtrl", ["$scope", "config", function ($scope, config) {
    $scope.url = config.url;
}]);

$.ajax({
    url: urlToCheck
}).fail(function () {
    myApp.constant('config', {
        url: '/fail-url'
    });
}).done(function () {
    myApp.constant('config', {
        url: '/done-url'
    });
}).always(function () {
    angular.bootstrap(document, ['myApp']);
});

答案 1 :(得分:0)

您可以利用$routeProvider,这可以让您延迟控制器实例化,直到您的promise得到解决。

$routeProvider为此目的公开了一个名为resolve的方法。请参阅AngularJS doc:

http://docs.angularjs.org/api/ngRoute.$routeProvider

这个优秀的SO问题中的其他信息:

AngularJS : Initialize service with asynchronous data

强烈推荐。