AngularJS: need to fire event every time an ajax call is started

后端 未结 4 1636
我在风中等你
我在风中等你 2020-12-13 10:33

I am trying to fire an event on $rootScope every time an ajax call is started.

var App = angular.module(\'MyApp\');

App.config(function ($httpProvider) {
           


        
相关标签:
4条回答
  • 2020-12-13 11:14

    You could always wrap $http in a service. Since services are only set up one time, you could just have the service factory set up the events for you. It feels a little hackish to me, honestly, but it's a good work around, since Angular doesn't have a global way to do this yet, unless something was added in 1.0.3 that I'm not aware of.

    Here's a plunker of it working

    And here's the code:

    app.factory('httpPreConfig', ['$http', '$rootScope', function($http, $rootScope) {
        $http.defaults.transformRequest.push(function (data) {
            $rootScope.$broadcast('httpCallStarted');
            return data;
        });
        $http.defaults.transformResponse.push(function(data){ 
            $rootScope.$broadcast('httpCallStopped');
            return data;
        })
        return $http;
    }]);
    
    app.controller('MainCtrl', function($scope, httpPreConfig) {
      $scope.status = [];
    
      $scope.$on('httpCallStarted', function(e) {
        $scope.status.push('started');
      });
      $scope.$on('httpCallStopped', function(e) {
        $scope.status.push('stopped');
      });
    
      $scope.sendGet = function (){ 
        httpPreConfig.get('test.json');    
      };
    });
    
    0 讨论(0)
  • 2020-12-13 11:21

    I have verified that this code will work as you expect. As I mentioned above, you are not retrieving the injector that you think you are and need to retrieve the one being used for your app.

    discussionApp.config(function($httpProvider) {
      $httpProvider.defaults.transformRequest.push(function(data) {
        var $injector, $log, $rootScope;
        $injector = angular.element('#someid').injector();
    
        $rootScope = $injector.get('$rootScope');
        $rootScope.$broadcast('httpCallStarted');
    
        $log = $injector.get('$log');
        $log.log('httpCallStarted');
        return data;
      });
    });
    
    0 讨论(0)
  • 2020-12-13 11:23

    Cagatay is right. Better use $http interceptors:

    app.config(function ($httpProvider, $provide) {
        $provide.factory('httpInterceptor', function ($q, $rootScope) {
            return {
                'request': function (config) {
                    // intercept and change config: e.g. change the URL
                    // config.url += '?nocache=' + (new Date()).getTime();
                    // broadcasting 'httpRequest' event
                    $rootScope.$broadcast('httpRequest', config);
                    return config || $q.when(config);
                },
                'response': function (response) {
                    // we can intercept and change response here...
                    // broadcasting 'httpResponse' event
                    $rootScope.$broadcast('httpResponse', response);
                    return response || $q.when(response);
                },
                'requestError': function (rejection) {
                    // broadcasting 'httpRequestError' event
                    $rootScope.$broadcast('httpRequestError', rejection);
                    return $q.reject(rejection);
                },
                'responseError': function (rejection) {
                    // broadcasting 'httpResponseError' event
                    $rootScope.$broadcast('httpResponseError', rejection);
                    return $q.reject(rejection);
                }
            };
        });
        $httpProvider.interceptors.push('httpInterceptor');
    });
    

    I think interceptors works for versions after 1.1.x. There was responseInterceptors before that version.

    0 讨论(0)
  • 2020-12-13 11:31

    The best way to do this is to use an http interceptor. Check this link

    0 讨论(0)
提交回复
热议问题