Angularjs中ajax单一方法的体系结构

时间:2013-09-04 11:17:47

标签: javascript ajax http angularjs service

我想了解如何为多个控制器设计单个ajax方法,这也会影响用户界面(例如,加载动画)。

理念是(没有承诺):

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

myApp.controller('myCtrl',
    function myCtrl($scope, myFactory){
        $scope.loading = false;
        $scope.someStuff = myFactory.getStuff(params);
});

myApp.factory('myFactory', function(myService){
    return{
        getStuff: function(params){
            return myService.ajax(params);
        }
    }
});

myApp.service('myService', function($http) {
    this.ajax = function(params){
        // switch $scope.loading = true; 
        // make request
        // return $http result
        // switch $scope.loading = false; 
    };
});

据我所知,我需要使用$ scope进行UI更改,并且应该将ajax-method用于自定义服务。 Angularjs中的服务不适用于$ scope,我不知道如何解决这个问题。

我认为,必须有一系列承诺服务。 怎么设计?

更新:我希望,随着文档更加完整和清晰。但角度用户社区已经很棒了。感谢。

3 个答案:

答案 0 :(得分:0)

在我的项目中,我定义了一个名为appState的服务,该服务包含({1}}和showGlobalSpinner等方法,用于修改hideGlobalSpinner上的变量。

基本上:

$rootScope

我接下来要做的是使用(…) .factory('appState', ['$rootScope', function ($rootScope) { return { showGlobalSpinner: function () { ++$rootScope.loadingInProgress; }, hideGlobalSpinner: function () { if ($rootScope.loadingInProgress > 0) { --$rootScope.loadingInProgress } } }; }]); 指令在我需要的地方显示微调器:

ng-show

在每个AJAX之前,我只需致电<div class="spinner" ng-show="loadingInProgress"></div>,在成功/错误之后,我致电AppState.showGlobalSpinner()

答案 1 :(得分:0)

您可以将此method添加到任何控制器:

.controller('HeaderCtrl',['$scope','httpRequestTracker', function($scope,httpRequestTracker) {
  $scope.hasPendingRequests = function () {
    return httpRequestTracker.hasPendingRequests();
  };
}]);


angular.module('services.httpRequestTracker', []);
angular.module('services.httpRequestTracker').factory('httpRequestTracker', ['$http', function($http){

  var httpRequestTracker = {};
  httpRequestTracker.hasPendingRequests = function() {
    return $http.pendingRequests.length > 0;
  };

  return httpRequestTracker;
}]);

答案 2 :(得分:0)

您可以使用HTTP拦截器,一些事件和指令来尝试更通用的方法:

<强>的Javascript

app.factory('myHttpInterceptor', function($q, $rootScope) {
  return function(promise) {
    $rootScope.$broadcast('RequestStarted');

    var success = function(response) {    
      $rootScope.$broadcast('RequestFinished', true);
    };

    var error = function(response) {        
      $rootScope.$broadcast('RequestFinished', false);
      return $q.reject(response);
    };

    promise.then(success, error);
    return promise;
  }
})
.config(function($httpProvider) {
  $httpProvider.responseInterceptors.push('myHttpInterceptor');
})
.directive('loading', function() {
  return {
    restrict: 'E',
    transclude: true,
    template: '<div ng-show="visible" ng-transclude></div>',
    controller: function($scope) {
      $scope.visible = false;

      $scope.$on('RequestStarted', function() {
        $scope.visible = true;
      });

      $scope.$on('RequestFinished', function() {
        $scope.visible = false;
      });
    }
  };
});

<强> HTML

...
<loading><h1>Loading...</h1></loading>
...

您可以看到有效的演示here

通过使用HTTP拦截器,您将能够跟踪Angular应用程序中$http服务(包括$resource)所做的每个HTTP请求,并相应地显示加载动画。