gsi*_*ank 22 error-handling service http interceptor angularjs
我想为我的$ http服务添加一个响应拦截器,以便进行错误处理.拦截器逻辑包括在必要的情况下使用$ http向服务器发送错误消息,但我不希望向服务器发送有关错误消息的错误消息,我的意思是,我希望在向服务器发送错误消息时禁用我的拦截器.
我的想法是创建一个名为'remote_log'的服务,并将所有向服务器发送错误所需的代码放入其中.该服务当然将使用$ http服务并将其置于其依赖列表中.
然后将拦截器的依赖关系添加到'remote_log'服务,并在需要向服务器发送错误时使用拦截器内的'remote_log'.问题是:
当$ http服务仍未实例化/可访问时,必须使用$ httpProvider定义拦截器,因此,拦截器代码内部不能依赖于$ http服务,因为发生了"循环依赖"错误.
我认为我唯一的选择是在我的'remote_log'中创建一个单独的$ http服务实例,这个实例不使用我在创建拦截器时设置的$ httpProvider配置.我的问题是:我怎么能这样做?还有其他想法吗?
Tha*_*ant 56
那么,为什么会出现错误?以下是该过程的快速概述:
使用angular.injector()创建依赖项.请注意,您将创建另一个$ http服务,独立于您的应用.
$httpProvider.interceptors.push(function($q) {
    $injector = angular.injector();
    return {
        response: function(response) {
            $injector.invoke(function($http) {
                // This is the exterior $http service!
                // This interceptor will not affect it.
            });
        }
    };
});
在您的拦截器中注入$ injector并在$ http初始化之后使用它来检索依赖关系,就在您需要它们时.这些依赖项是您的应用程序的注册服务,不会重新创建!
$httpProvider.interceptors.push(function($q, $injector) {
    return {
        response: function(response) {
            $injector.invoke(function($http, someService) {
                // $http is already constructed at the time and you may
                // use it, just as any other service registered in your
                // app module and modules on which app depends on.
            });
        }
    };
});
如果您使用第二个解决方案,实际上有两个问题:
$ http服务的'config'参数只是一个对象.您可以创建一个约定,提供自定义参数并在拦截器中识别它们.
例如,让我们添加"nointercept"属性来配置并尝试复制每个用户请求.这是一个愚蠢的应用程序,但是用于理解行为的有用示例:
$httpProvider.interceptors.push(function($q, $injector) {
    return {
        response: function(response) {
            if (response.config.nointercept) {
                return $q.when(response); // let it pass
            } else {
                var defer = $q.defer();
                $injector.invoke(function($http) {
                    // This modification prevents interception:
                    response.config.nointercept = true;
                    // Reuse modified config and send the same request again:
                    $http(response.config)
                        .then(function(resp) { defer.resolve(resp); },
                              function(resp) { defer.reject(resp); });
                });
                return defer.promise;
            }
        }
    };
});
在拦截器中测试属性后,您可以阻止控制器和服务中的拦截:
app.controller('myController', function($http) {
    // The second parameter is actually 'config', see API docs.
    // This query will not be duplicated by the interceptor.
    $http.get('/foo/bar', {nointercept: true})
        .success(function(data) {
            // ...
        });
});
| 归档时间: | 
 | 
| 查看次数: | 7753 次 | 
| 最近记录: |