【问题标题】:Callback / dispatch event from Interceptor to Directives从拦截器到指令的回调/调度事件
【发布时间】:2016-06-14 21:50:16
【问题描述】:

我有一个带有 AngularJS 的应用程序。

这个应用程序使用了许多带有和不带有隔离范围的指令。有两个使用 sub/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 指令。这样做,我的服务就不必处理那些“开始/结束请求”事件。

但我不知道如何从我的拦截器“访问”指令,或者如何从指令向我的拦截器添加回调。可能吗?或者唯一的方法是来自 Interceptor 的“rootScope 广播”?

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

【问题讨论】:

    标签: javascript angularjs signals


    【解决方案1】:

    我找到的答案很简单:因为拦截器只是 Angular 的工厂,所以它就像任何其他服务一样被注入到我的控制器中。

    所以,最后,这是我的拦截器:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-31
      • 2020-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-05
      相关资源
      最近更新 更多