2012-12-06 14 views
15

ajax çağrısı her başlatıldığında $ rootScope'ta bir olayı tetiklemeye çalışıyorum.AngularJS: ajax çağrısı her başlatıldığında olayı tetiklemeniz gerekir

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

olay 'httpCallStarted' o ateş olmak değil. Yapılandırma bloklarında $ rootScope veya başka bir örnek hizmetinin kullanılmasının doğru olmadığından şüpheleniyorum. Eğer öyleyse, bir çağrı yaptığım her seferde bir config nesnesini geçmek zorunda kalmadan, bir http çağrısı her başladığında bir olayı nasıl alabilirim? peşin

+0

Angularim, angular.injector (['ng']) çağrılarının yanlış gittiğiniz yerdir. Bu, aslında uygulamanızla birlikte kullanılan enjektör işlevini size geri vermez ve bu nedenle $ rootScope'u almaya çalıştığınızda, aslında düşündüğünüzden farklı bir $ rootScope elde edersiniz. Gerçek enjektörü nasıl elde edeceğimi bilmenin tek yolu, angular.element (someselector) .injector() kullanımıdır ve daha sonra buna .get ('$ rootScope') diyebilirsiniz. Yine de bir yapılandırma bloğunda bunu yapmanın sorunlarının olup olmadığını bilmiyorum. –

cevap

16

yılında

teşekkürler Her zaman bir hizmette $ http sarabilirdiniz. Servisler sadece bir kez kurulduğundan, hizmet fabrikasının sizin için etkinlikleri ayarlamasını sağlayabilirsiniz. Dürüst olmak gerekirse, benim için biraz aceleci geliyor, ama bu iyi bir çalışma, çünkü Angular'ın henüz farkında olmadan 1.0.3'te bir şey eklenmediği sürece bunu yapmak için küresel bir yolu yok.

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

Bana göre iyi görünüyor, ancak $ http hizmetine değil, özel httpPreConfig'e bağlı olduğu için bu sorunu $ kaynak hizmetinde nasıl çözebilirim? – bfcamara

+0

I * düşünüyorum * ilk kez bu servise başvurursanız, tüm aramalar için $ http, hatta $ kaynaktakiler için varsayılanları günceller. –

+0

Çalışıyor. Çok teşekkür ederim – bfcamara

12

Ben beklediğiniz gibi bu kod çalışacak doğruladıktan:

Here's a plunker of it working

Ve burada kod. Yukarıda belirttiğim gibi, sizin kullandığınız ve uygulamanız için kullanılanı almanız gerektiğini düşündüğünüz enjektörü almıyorsunuz.

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; 
    }); 
}); 
+2

Doğru cevap budur. –

+1

Tamamen doğru olması için bir veri argümanı almanız ve bazı verileri de geri göndermeniz gerekir. – bfcamara

3

Bunu yapmanın en iyi yolu bir http interceptor kullanmaktır. Check out this Link

11

Çağatay haklı. Daha iyi kullanım $http önleyicilerin:

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

Ben 1.1.x. sonra sürümleri için interceptors eser düşünüyorum Bu sürümden önce responseInterceptors vardı.

+0

Cevabımda bir örnek eklemedim, ancak evet projemde kullandığım tam olarak bu. –

+1

Bu çok iyi bir cevaptır. Interceptor içinde bir servis kullanmak zorunda kaldım (spikeri göstermek/gizlemek için), ama göstermek için .config kullanmıştım ve şimdi .config'te hizmet kullanmak mümkün değil, şimdi bu çözüm ile her şey sorunsuz ve iyi çalışıyor! –

+0

bu doğru cevap olmalıdır – MilesStanfield

İlgili konular