Нет провайдера ConnectionBackend при наследовании от Http
Я пытаюсь создать оболочку вокруг встроенной службы Http в angular 2, чтобы иметь возможность добавлять настраиваемое поведение (заголовки, параметры и т.д.).
Итак, я создал обычный класс (а не службу) и наследовал его от Http.
Определение класса
import {
Http,
ConnectionBackend,
RequestOptions,
RequestOptionsArgs,
Headers
} from '@angular/http';
import { Observable } from 'rxjs/Observable';
import {tamamApiUrl} from '../constants';
import {CustomQueryEncoder} from './CustomQueryEncoder';
import 'rxjs/Rx';
export class BaseHttp extends Http {
protected applicationDataService;
protected baseUrl: string = tamamApiUrl;
protected encoder: CustomQueryEncoder;
constructor(backend:ConnectionBackend,
defaultOptions: RequestOptions, applicationDataService: any) {
super(backend, defaultOptions);
this.applicationDataService = applicationDataService;
}
get(url: string, options?: RequestOptionsArgs): Observable<any> {
this.addDefaultOptions(options);
return super.get(url, options);
}
post(url: string, body: any, options?: RequestOptionsArgs): Observable<any> {
this.addDefaultOptions(options);
this.addDefaultPostOptions(options);
return super.post(url, body, options);
}
private addDefaultOptions(options?: RequestOptionsArgs): RequestOptionsArgs {
if (options == null) {
options = new RequestOptions();
}
if (options.headers == null) {
options.headers = new Headers();
}
const applicationData = this.applicationDataService.getApplicationData();
if (applicationData.applicationKey) {
options.headers.append('application-id', applicationData.applicationKey);
}
if (applicationData.secretKey) {
options.headers.append('secret-key', applicationData.secretKey);
}
if (applicationData.userToken) {
options.headers.append('user-token', applicationData.userToken);
}
return options;
}
private addDefaultPostOptions(options): void {
options.headers.append('Content-Type', 'application/json');
}
/*private requestInterceptor(): void {
this.loaderService.showPreloader();
}
private responseInterceptor(): void {
this.loaderService.hidePreloader();
}*/
}
Чем я создал службу, унаследованную от этого класса, чтобы я мог позже ее использовать и использовать для своих целей.
import { Headers, URLSearchParams } from '@angular/http';
import {tamamRootUrl} from '../constants';
import {BaseHttp} from '../api/BaseHttp';
import { Injectable } from '@angular/core';
import {
ConnectionBackend,
RequestOptions,
} from '@angular/http';
import {ApplicationService} from './ApplicationService';
@Injectable()
export class InspectionHttpService extends BaseHttp{
protected baseUrl: string = tamamRootUrl;
protected params: URLSearchParams = new URLSearchParams();
constructor(backend: ConnectionBackend,
defaultOptions: RequestOptions, protected applicationService: ApplicationService) {
super(backend, defaultOptions, applicationService);
}
getRootUrl() {
return this.baseUrl;
}
}
Определение службы
После того, как я попытаюсь ввести созданную службу в компонент, я получаю сообщение об ошибке:
error_handler.js: 47 ИСКЛЮЧЕНИЕ: Неподготовлено (в обещании): Ошибка: ошибка. /VehiclesListComponent class VehiclesListComponent_Host - встроенный шаблон: 0: 0, вызванный: Нет провайдера для ConnectionBackend!
Я попытался найти решение с использованием stack-overflow, но он видит, что у HtpModule уже должно быть все необходимое для правильной работы.
Может ли кто-нибудь мне помочь? Где проблема?
Ответы
Ответ 1
Вы не можете просто добавить его к таким провайдерам
providers: [ ApplicationService, InspectionHttpService ]
Если вы это сделаете, то Angular попытается создать его, и он не найдет поставщика для ConnectionBackend
Вам нужно использовать factory, где вы можете просто передать XHRBackend
(который реализует ConnectionBackend
)
imports: [HttpModule],
providers: [
ApplicationService,
{
provide: InspectionHttpService,
deps: [XHRBackend, RequestOptions, ApplicationService],
useFactory: (backend, options, aplicationService) => {
return new InspectionHttpService(backend, options, applicationService);
}
}
]
При этом вы можете ввести его как InspectionHttpService
.
constructor(private http: InspectionHttpService) {}
Если вы хотите использовать его как Http
, вам нужно изменить provide
на Http
вместо InspectionHttpService
. Но это переопределяет любую возможность использовать обычный Http
, если вам когда-либо понадобится.
UPDATE
В некоторых средах, возможно, вы можете получить сообщение об ошибке с указанным выше кодом. Я забыл точное сообщение об ошибке, но это даст вам предлагаемое решение для извлечения функции factory, т.е.
export function httpFactory(backend: XHRBackend, options: RequestOptions,
service: ApplicationService) {
return new InspectionHttpService(backend, options, service);
}
useFactory: httpFactory
Из того, что я помню, я думаю, что ошибка имеет какое-то отношение к AoT
Ответ 2
При расширении службы Http вам необходимо ввести backend и опции для родительского класса:
@Injectable()
export class HttpInterceptor extends Http {
constructor(
backend: XHRBackend,
options: RequestOptions,
...
) {
super(backend, options);
}
...
}