首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AngularJS httpInterceptors和toastr

AngularJS httpInterceptors和toastr
EN

Stack Overflow用户
提问于 2015-08-11 15:48:22
回答 1查看 927关注 0票数 4

我现在有一个拦截器来处理我的$http错误。看起来有点像这样:

代码语言:javascript
复制
.factory('RequestsErrorHandler', ['$q', '$injector', '$rootScope', 'ErrorService', function ($q, $injector, $rootScope, service) {
    var specificallyHandled = function (specificallyHandledBlock) {
        specificallyHandleInProgress = true;

        try {
            return specificallyHandledBlock();
        } finally {
            specificallyHandleInProgress = false;
        }
    };

    var responseError = function (rejection) {

        // Create the variable for handling errors
        var shouldHandle = (rejection && rejection.config && rejection.config.headers && rejection.config.headers['handle-generic-errors']);

        // If we should handle an error
        if (shouldHandle) {

            // Get our error
            var error = service.process(rejection);

            // Assign our error to the rootScope
            $rootScope.serverError = error;

            // Redirect to our error screen
            $injector.get('$state').transitionTo('error');
        }

        // Fallback, reject the promise
        return $q.reject(rejection);
    };

    return {
        specificallyHandled: specificallyHandled,
        responseError: responseError
    };
}])

我在我的应用程序配置中设置了这样的设置:

代码语言:javascript
复制
.config(['$httpProvider', '$provide', function ($httpProvider, $provide) {
    $httpProvider.interceptors.push('RequestsErrorHandler'); // Add our interceptor to handle http requests

    // Decorate $http to add a special header by default
    function addHeaderToConfig(config) {
        config = config || {};
        config.headers = config.headers || {};

        // Add the header unless user asked to handle errors himself
        if (!specificallyHandleInProgress) {
            config.headers['handle-generic-errors'] = true;
        }

        return config;
    }

    // The rest here is mostly boilerplate needed to decorate $http safely
    $provide.decorator('$http', ['$delegate', function ($delegate) {
        function decorateRegularCall(method) {
            return function (url, config) {
                return $delegate[method](url, addHeaderToConfig(config));
            };
        }

        function decorateDataCall(method) {
            return function (url, data, config) {
                return $delegate[method](url, data, addHeaderToConfig(config));
            };
        }

        function copyNotOverriddenAttributes(newHttp) {
            for (var attr in $delegate) {
                if (!newHttp.hasOwnProperty(attr)) {
                    if (typeof ($delegate[attr]) === 'function') {
                        newHttp[attr] = function () {
                            return $delegate.apply($delegate, arguments);
                        };
                    } else {
                        newHttp[attr] = $delegate[attr];
                    }
                }
            }
        }

        var newHttp = function (config) {
            return $delegate(addHeaderToConfig(config));
        };

        newHttp.get = decorateRegularCall('get');
        newHttp.delete = decorateRegularCall('delete');
        newHttp.head = decorateRegularCall('head');
        newHttp.jsonp = decorateRegularCall('jsonp');
        newHttp.post = decorateDataCall('post');
        newHttp.put = decorateDataCall('put');

        copyNotOverriddenAttributes(newHttp);

        return newHttp;
    }]);
}])

现在,一切都很顺利。但是,对于每一个未处理的错误,它都会变得越来越烦人,进入一个新的视图。因此,我想我可能会把它作为一个烤面包错误来做,所以我把我的服务改为:

代码语言:javascript
复制
.factory('RequestsErrorHandler', ['ErrorService', 'toastr', function (service, toastr) {
    var specificallyHandled = function (specificallyHandledBlock) {
        specificallyHandleInProgress = true;

        try {
            return specificallyHandledBlock();
        } finally {
            specificallyHandleInProgress = false;
        }
    };

    var responseError = function (rejection) {

        // Create the variable for handling errors
        var shouldHandle = (rejection && rejection.config && rejection.config.headers && rejection.config.headers['handle-generic-errors']);

        // If we should handle an error
        if (shouldHandle) {

            // Get our error
            var error = service.process(rejection);

            // Display the error
            toastr.error(error);
        }

        // Fallback, reject the promise
        return $q.reject(rejection);
    };

    return {
        specificallyHandled: specificallyHandled,
        responseError: responseError
    };
}])

但是,当我试图运行这个程序时,我会发现一个错误:

循环依赖性发现:$http <- $templateRequest <- $$animateQueue <- $animate <- RequestsErrorHandler <- $http <- $templateFactory <- $view <- $state

我不知道怎么解决这个问题,还有人知道吗?

EN

回答 1

Stack Overflow用户

发布于 2015-08-11 15:57:21

对于solev这类循环依赖问题,有两种简单的方法。

  1. 通过使用事件来解耦服务:当在拦截器中检测到错误时,在根范围上广播一个事件(带有错误信息)。在toastr服务中(或在使用toastr的服务中),在根范围内侦听这些事件并显示它们。
  2. 而不是在拦截器中注入toastr,而是注入$injector服务。当您需要一个toastr实例时,调用$injector.get('toastr')
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31946379

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档