2016-06-13 23 views
0

我有一個AngularJS應用程序。從攔截器到指令的回調/調度事件

這個應用程序使用許多指令,無論是否有獨立的範圍。有兩種服務使用子/ pub系統加載和分派數據。沒什麼大不了。

現在我有以下情況:每次任何服務啓動「get/post/etc」方法時,我想顯示預加載器。當數據返回時,我想隱藏預加載器。好吧,服務派遣一個事件,Preloader指令監聽這個事件,並且在成功/錯誤回調中調度一個新事件,並且隱藏預加載器。

但在現實世界中,它沒有用處。我需要從我的服務中派發類似「onStartLoad」的事件,這會污染代碼。這裏是我的服務裏面一個方法的一個例子:

var service = { 
    onOffersLoaded: new signals.Signal(), 
    // (... many other events/signals here) 

    // On start any request event: 
    onStartAny: new signals.Signal(), 

    // On end any request event:  
    onEndAny: new signals.Signal(), 

    getOffers: function(store) { 
     // Dispatch that the request is about to begin: 
     service.onStartAny.dispatch(); 

     var url = config.apiUrl + "/my-ending-point-here"; 
     $http.get(url) 
      .success(function(data) { 
       // Dispatch that the request got back: 
       service.onEndAny.dispatch(); 

       service.onOffersLoaded.dispatch(data, store); 
      }) 
      .error(function(error) { 
       // Dispatch that the request got back: 
       service.onEndAny.dispatch(); 

       service.onError.dispatch(error); 
      }); 
    }, 

正如你所看到的,我需要傳播service.onStartAny.dispatch();service.onEndAny.dispatch();各地我的方法。這是非常煩人和骯髒。我想我可以用Interceptor。當數據進入或離開我的應用程序時,攔截器可以「捕捉」這些請求,並且可以將事件分派給我的Preloader指令。這樣做,我的服務不必處理那些「開始/結束請求」事件。

但我不知道如何從我的攔截器「訪問」該指令或如何從指令添加回調到我的攔截器。可能嗎?或者唯一的辦法就是攔截器的「rootScope broadcast」?

任何幫助是非常感激。 謝謝。

回答

0

我發現的答案很簡單:由於攔截器只是角度的工廠,它就像其他服務一樣注入到我的控制器中。

那麼,到底,這是我的攔截器:

angular.module("offersApp").factory("preloaderInterceptor", function($q) { 
"ngInject"; 

var interceptor = { 

    onRequestStart: new signals.Signal(), 
    onRequestEnd: new signals.Signal(), 

    request: function(config) { 
     interceptor.onRequestStart.dispatch(); 
     return config; 
    }, 

    requestError: function(rejection) { 
     interceptor.onRequestEnd.dispatch(); 
     return $q.reject(rejection); 
    }, 

    response: function(response) { 
     interceptor.onRequestEnd.dispatch(); 
     return response; 
    }, 

    responseError: function(rejection) { 
     interceptor.onRequestEnd.dispatch(); 
     return $q.reject(rejection); 
    } 

}; 

return interceptor; 
}); 

這是我的預加載指令:

angular.module("offersApp").directive("preloader", function ($timeout, preloaderInterceptor) { 
    "ngInject"; 
    return { 
     template: '<div id="preloader"><div class="loading"></div></div>', 
     replace: true, 
     restrict: "EA", 
     scope: {}, 

     link: function (scope, element, attrs, ctrl) { 

      var showPreloader = function() { 
       element.css({display: 'block', opacity: 1}); 
      } 

      var hidePreloader = function() { 
       element.css({opacity: 0}); 
       var promise = $timeout(function() { 
        element.css({display: 'none'}); 
       }, 600); 
      } 

      preloaderInterceptor.onRequestStart.add(showPreloader); 
      preloaderInterceptor.onRequestEnd.add(hidePreloader); 
     } 
    }; 
});