Angular의 두 가지 사례가 필요합니다.JS $http 서비스?
오류 처리를 위해 $http 서비스에 응답 인터셉터를 추가하고 싶습니다.인터셉터 로직에는 필요한 경우 $http를 사용하여 오류 메시지를 서버에 전송하는 것이 포함되지만, 오류 메시지에 대한 오류 메시지를 서버에 전송하는 것은 원하지 않습니다. 즉, 서버에 오류 메시지를 전송하는 동안 인터셉터를 비활성화하고 싶습니다.
제 아이디어는 'remote_log'라는 이름의 서비스를 만들어서 서버에 오류를 전송하는 데 필요한 모든 코드를 입력하는 것이었습니다.그 서비스는 당연히 $http 서비스를 이용하고 종속성 목록에 포함됩니다.
그런 다음 'remote_log' 서비스에 인터셉터의 종속성을 추가하고, 서버에 오류를 전송해야 할 때 인터셉터 내부의 'remote_log'를 사용합니다.문제는 다음과 같습니다.
$http 서비스가 여전히 인스턴스화/액세스할 수 없는 경우에는 $httpProvider를 사용하여 인터셉터를 정의해야 합니다. 따라서 "Circular dependency" 오류가 발생하므로 인터셉터 코드 내부가 해당 $http 서비스에 종속될 수 없습니다.
내 'remote_log' 안에 별도의 $http 서비스 인스턴스를 만드는 것이 나의 유일한 방법이라고 생각합니다. 인터셉트를 생성하는 동안 내가 설정한 $httpProvider 구성을 사용하지 않는 인스턴스입니다.제 질문은 다음과 같습니다.내가 어떻게 그럴 수 있을까?다른 생각 있나요?
1. 순환 종속성 문제입니다.
그렇다면 왜 오류가 나타나는 것일까요?다음은 프로세스에 대한 간단한 개요입니다.
- $http 서비스를 요청합니다.
- $httpProvider가 구축을 요청합니다.
- 공사 중에 인터셉터를 등록하면 $http 서비스가 아직 존재하지 않습니다.
- 순환 의존성 오류가 발생합니다.
첫 번째 해결책.
각도를 사용하여 종속성을 만듭니다.주입기앱에서 독립적으로 다른 $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.
});
}
};
});
2. 가로채기 방지 문제.
두 번째 솔루션을 사용할 경우 실제로 두 가지 문제가 발생합니다.
- 인터셉터 내부에서 $http 서비스를 사용할 경우 무한 인터셉션으로 끝날 수 있습니다. 요청을 보내고, 인터셉터가 이를 잡고, 다른 것을 잡고, 다시 보내고 등입니다.
- 때로는 요청이 가로채는 것을 방지하고자 할 때도 있습니다.
$http 서비스의 'config' 매개 변수는 개체일 뿐입니다.사용자 지정 매개변수를 제공하고 인터셉터에서 이를 인식하는 규약을 작성할 수 있습니다.
예를 들어, "no intercept" 속성을 구성에 추가하고 모든 사용자 요청을 복제해 보겠습니다.이는 어리석은 응용 프로그램이지만 동작을 이해하는 데 유용한 예입니다.
$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) {
// ...
});
});
답변에 설명된 내용을 사용했지만 익명 기능으로는 작동하지 않았기 때문에 공장에서 구문을 사용했습니다.
(function(angular){
angular.module('app', [])
.config([
'$httpProvider',
function($httpProvider) {
$httpProvider.interceptors.push('Interceptor');
}
])
.factory('Interceptor', [
'$injector',
InterceptorFactory
]);
function InterceptorFactory($injector){
return {
request: function(config) {
var ServiceWithHttp = $injector.get('ServiceWithHttp');
// Use ServiceWithHttp
return config;
}
};
}
}(window.angular));
언급URL : https://stackoverflow.com/questions/14681654/i-need-two-instances-of-angularjs-http-service-or-what
'source' 카테고리의 다른 글
@미디어 최소 너비 & 최대 너비 (0) | 2023.11.07 |
---|---|
오라클 디버깅 기법 (0) | 2023.11.07 |
각 리소스 호출 및 $q (0) | 2023.11.07 |
요소의 XSLT 이름이 있습니까? (0) | 2023.11.07 |
printk와 pr_info의 차이 (0) | 2023.11.07 |