我需要两个AngularJS $ http服务的实例呢? [英] I need two instances of AngularJS $http service or what?

查看:175
本文介绍了我需要两个AngularJS $ http服务的实例呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为我的$ http服务添加一个响应拦截器以进行错误处理。拦截器逻辑包括使用$ http发送错误消息到服务器,在必要的情况下,但是,我不想向服务器发送有关错误消息的错误消息,我的意思是,我想要在发送错误时禁用我的拦截器消息到服务器。

I want add a response interceptor to my $http service for error handling purposes. The interceptor logic include send errors messages to server using $http in case necessary, BUT I don't want send errors messages to the server about errors messages, I mean, I want disable my interceptor while sending error message to the server.

我的想法是创建一个名为remote_log的服务,并将其中的所有代码发送到服务器。那个服务当然会使用$ http服务并将其放在依赖列表中。

My idea was create a service named 'remote_log' and put inside it all the code needed to send error to server. That service of course will use the $http service and have it in its dependency list.

然后添加作为拦截器的依赖关系到'remote_log'服务,并使用当需要向服务器发送错误时,拦截器中的'remote_log'。问题是:

Then add as dependency of the interceptor to the 'remote_log' service, and use the 'remote_log' inside the interceptor when need send errors to the server. The problems is that:

当$ http服务仍未实例化/可访问时,拦截器必须使用$ httpProvider定义,因此拦截器代码内不能一个依赖于$ http服务,因为循环依赖错误发生。

Interceptors must be defined using the $httpProvider when the $http service still is not instantiated/accessible, so, inside the interceptor code can't be a dependency to that the $http service because a "Circular dependency" error happen.

我认为我唯一的选择是创建一个单独的$ http服务实例在我的' remote_log,一个不使用我在创建拦截器时设置的$ httpProvider配置的实例。我的问题是:我该怎么做?任何其他想法?

I think my only option is create a separate instance of the $http service inside my 'remote_log', an instance that don't uses the $httpProvider configuration I set while creating the interceptor. My question is: How can I do that? Any other ideas?

推荐答案

1。循环依赖问题。



那么为什么出现错误?以下是对此过程的简要概述:

1. Circular dependency problem.

So, why does the error appear? Here is a quick overview of the process:


  1. $ http服务被要求。

  2. $ httpProvider请求构建它。

  3. 在构建期间,您注册拦截器,请求$ http服务尚未存在。

  4. 您会收到循环依赖错误

  1. $http service is requested.
  2. $httpProvider is asked to construct it.
  3. During construction you register interceptor, that requests $http service not existing yet.
  4. You get "Circular dependency" error.


使用angular.injector()创建您的依赖关系。请注意,您将创建另一个$ http服务,独立于您的应用程序。

Create your dependency using angular.injector(). Notice, that you will create another $http service, independent from your app.

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


在拦截器中注入$注射器,并使用它在$ http初始化之后,在您需要它们时检索依赖关系。这些依赖关系是您的应用程序的注册服务,不会重新创建!

Inject $injector in your interceptor and use it to retrieve dependencies after $http initialization, right at the time you need them. These dependencies are registered services of your app and will not be created anew!

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


如果您使用第二个解决方案,实际上有两个问题:

If you use the second solution, there are actually two problems:


  1. 如果您在
    拦截器中使用$ http服务,则可能会导致无限次拦截:您发送
    请求,拦截器捕获它,发送另一个,捕获另一个,再次发送
    ,等等。

  2. 有时您只希望阻止请求被拦截。

$ http服务的'config'参数只是一个对象。您可以创建一个约定,提供自定义参数并在拦截器中识别它们。

The 'config' parameter of $http service is just an object. You may create a convention, providing custom parameters and recognizing them in your interceptors.

例如,我们将nointercept属性添加到配置中,并尝试重复每个用户请求。这是一个愚蠢的应用程序,但有用的例子来了解行为:

For example, let's add "nointercept" property to config and try duplicate every user request. This is a silly application, but useful example to understand the behavior:

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

在拦截器中进行属性测试时,可能会阻止在控制器和服务中的拦截:

Having the testing for property in interceptor, you may prevent the interception in controllers and services:

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) {
            // ...
        });

});

这篇关于我需要两个AngularJS $ http服务的实例呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆