我有一个使用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广播"来自Interceptor?
任何帮助都非常感谢。 谢谢。
答案 0 :(得分: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);
}
};
});