16

ajax呼び出しが開始されるたびに、$rootScopeでイベントを発生させようとしています。

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

App.config(function ($httpProvider) {
    //add a transformRequest to preprocess request
    $httpProvider.defaults.transformRequest.push(function () {
        //resolving $rootScope manually since it's not possible to resolve instances in config blocks
        var $rootScope = angular.injector(['ng']).get('$rootScope');
        $rootScope.$broadcast('httpCallStarted');

       var $log = angular.injector(['ng']).get('$log');
       $log.log('httpCallStarted');
    });
});

イベント「httpCallStarted」は発生していません。構成ブロックで$rootScopeまたはその他のインスタンスサービスを使用するのは正しくないと思います。もしそうなら、私が電話をかけるたびに設定オブジェクトを渡す必要なしに、http呼び出しが始まるたびにイベントを取得するにはどうすればよいですか?

前もって感謝します

4

4 に答える 4

17

サービスで $http をいつでもラップできます。サービスは 1 回だけセットアップされるため、サービス ファクトリにイベントをセットアップしてもらうことができます。正直なところ、私には少しハックな気がしますが、1.0.3 で何かが追加されていない限り、Angular にはこれを行うためのグローバルな方法がまだないため、良い回避策です。

これが機能するプランカーです

コードは次のとおりです。

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');    
  };
});
于 2012-12-06T15:56:44.903 に答える
12

このコードが期待どおりに機能することを確認しました。上で述べたように、あなたは自分が思っているインジェクターを取得しておらず、アプリに使用されているインジェクターを取得する必要があります。

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;
  });
});
于 2012-12-07T16:35:58.057 に答える
12

カガタイは正しい。$httpインターセプターをより適切に使用します。

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');
});

interceptors1.1.x 以降のバージョンで動作すると思います。responseInterceptorsそのバージョンの前にありました。

于 2014-01-31T03:01:26.697 に答える
4

これを行う最善の方法は、http インターセプターを使用することです。このリンクを確認してください

于 2014-01-29T23:03:36.440 に答える