从拦截器到指令的回调/调度事件

时间:2016-06-13 23:13:45

标签: javascript angularjs signals

我有一个使用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?

任何帮助都非常感谢。 谢谢。

1 个答案:

答案 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);
        }
    };
});