Angular Factory依赖问题

时间:2016-09-21 18:34:25

标签: angularjs

我有两个工厂:ApiService和LocationService。

在ApiService中,我想从LocationService将使用的$ http调用返回端点。

但是当控制器调用LocationService时,它似乎不会等待来自ApiService的响应。下面是一些代码片段,在ApiService中,当我最终使它工作时,我会将其缓存,所以我不需要每次都要调用服务器来获取端点:

    services.factory("ApiService", ["$location", "$http", function ($location, $http) {
    return {
        getEndpointUrl: function () {
            var endpoint;

            $http({
                method: 'GET',
                url: '/site/apiendpoint'
            }).then(function successCallback(response) {
                endpoint = response.data;
                console.log(endpoint);
                return endpoint;
            }, function errorCallback(response) {
                console.error('Error retrieving API endpoint');
            });
        }
    }
}]);

这是位置服务,它使用ApiService:

    services.factory("LocationService", ["$resource", "ApiService", function ($resource, apiService) {
    var baseUri = apiService.getEndpointUrl();
    return $resource(baseUri + '/location', {}, {
        usStates: { method: 'GET', url: baseUri + '/location/us/states' }
    });
}]);

当我的控制器试图调用LocationService.usStates时,baseUri是未定义的。我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

原因是因为您的getEndpointUrl函数是异步的,并且它没有返回值。

由于您的LocationService使用$资源并依赖于baseUri,我建议将该数据与初始页面加载一起引导并使其成为常量,如:

angular.module('yourModule').constant('baseUrl', window.baseUrl);

然后您的服务会将其注入以创建您的资源:

   services.factory("LocationService", ["$resource", "ApiService", "baseUrl", function ($resource, apiService, baseUrl) {
       return $resource(baseUrl + '/location', {}, {
          usStates: { method: 'GET', url: baseUrl + '/location/us/states' }
       });
   }]);

答案 1 :(得分:0)

ApiService中,您实际上并未从getEndpointUrl()返回值。你如何从ApiService返回一个承诺,然后以同步的方式在LocationService中使用它?

services.factory("ApiService", ["$location", "$http", function($location, $http) {
    return {
        getEndpointUrl: function() {
            var endpoint;

            return $http({
                method: 'GET',
                url: '/site/apiendpoint'
            });
        }
    }
}]);

services.factory("LocationService", ["$resource", "ApiService", function($resource, apiService) {
    return {
        getLocations: function() {
            return apiService.getEndpointUrl().then(function successCallback(response) {
                var baseUri = response.data;

                return $resource(baseUri + '/location', {}, {
                    usStates: { method: 'GET', url: baseUri + '/location/us/states' }
                });

            }, function errorCallback(response) {
                console.error('Error retrieving API endpoint');
            });
        }
    };
}]);

然后在你的控制器中:

LocationService.getLocations().then(function(data) {
    $scope.statesResult = data.result.states;  
});