如何在AngularJS中实现通用HTTP服务?

时间:2014-03-28 01:54:33

标签: angularjs

在我的角度模块中,我为所有的ajax请求编写了一个通用的http处理程序。'

我当时希望我可以跨控制器使用这项服务,但我的问题是承诺似乎是全球性的。

一旦ControllerOne使用mapi_loader服务,当我加载AnotherController(按ng-click="go('/$route_to_load_another_controller')")时,AnotherController会加载一个已从ControllerOne返回的承诺{1}}尽管他们fetch的网址完全不同。

所以我想我的问题是我如何编写一个可以跨控制器使用的服务?我是否真的需要为每个控制器编写单独的服务,其中唯一的代码区别是为$http.jsonp传递的URL?

angular.module('myAppControllers',[])
  .service('mapi_loader', ['$http', function($http) {
    var promise;
    var myService = {
      fetch: function(url) {
        if ( !promise ) {
          promise = $http.jsonp(url)
          .then(function (response) {
            return response.data.nodes;
          });
        }
        return promise;
      }
    };
    return myService;
  }])
  .controller('ControllerOne', ['$scope', 'mapi_loader', function ($scope, mapi_loader) {
    mapi_loader
    .fetch("http://host.com/mapi_data_for_controller_one?callback=JSON_CALLBACK")
    .then(function(data) {
      $scope.useme = data;
    });
  }])
  .controller('AnotherController', ['$scope', 'mapi_loader', function ($scope, mapi_loader) {
    mapi_loader
    .fetch("http://host.com/mapi_data_for_another_controller?callback=JSON_CALLBACK")
    .then(function(data) {
      $scope.useme = data;
    });
  }])
;

1 个答案:

答案 0 :(得分:0)

尝试这样的事情

angular.module('myAppControllers',[])
  .service('mapi_loader', function($http) {
    var alreadyLoading = {};
    return {
      fetch: function(url) {
        if ( url in alreadyLoading ) {
          return alreadyLoading[url];
        }
        return alreadyLoading[url] = $http.jsonp(url)
         .then(function (response) {
           delete alreadyLoading[url];
           return response.data.nodes;
        });
      }
    };
  })
  .controller('ControllerOne', function ($scope, mapi_loader) {
    ...
  })
  .controller('AnotherController', function ($scope, mapi_loader) {
    ...
  });