我需要AngularJS $ http服务还是什么的两个实例? [英] I need two instances of AngularJS $http service or what?
问题描述
我要响应拦截器添加到我的$ 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,并把它里面的所有发送错误到服务器所需的code服务。当然,这服务将使用$ 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:
拦截器必须使用被定义的$ httpProvider当$ HTTP服务仍无法实例化/访问,因此,拦截器code里面不能成为一种依赖,将$ 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.
我想我唯一的选择就是创建我的'remote_log',不使用$ httpProvider配置,同时创造了拦截我设置一个实例里面的$ http服务的一个单独的实例。我的问题是:我怎样才能做到这一点?任何其他的想法?
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. Circular dependency problem.
So, why does the error appear? Here is a quick overview of the process:
- $ HTTP服务请求。
- $ httpProvider被要求来构建它。
- 在施工过程中您注册拦截器,请求$ http服务不存在呢。
- 您获得循环依赖的错误。
创建您的使用依赖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:
- 如果您使用在$ http服务的
拦截器,你可能最终与无限的拦截:你送
请求拦截器捕获它,发送另一个,另一个捕捉,
再次发送,等等。 - 有时候,你只想prevent请求被截取。
$ HTTP服务的'配置'参数只是一个对象。您可以创建一个惯例,提供自定义参数,并在你的拦截器识别它们。
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;
}
}
};
});
具有拦截财产的测试,您可能prevent在控制器和服务截取:
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屋!