从 Http 继承时没有 ConnectionBackend 的提供者
No provider for ConnectionBackend while inheriting from Http
我正在尝试围绕 angular 2 中的内置 Http 服务制作一个包装器,以便有可能添加自定义行为(headers、参数等)
所以我创建了一个普通的class(不是服务)并继承自Http。
Class definition
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();
}*/
}
然后我创建了一个继承自此 class 的服务,以便我可以稍后注入它并用于我的目的。
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;
}
}
Service definition
在我尝试在组件中注入创建的服务后,我收到一个错误:
error_handler.js:47 异常:未捕获(承诺):错误:./VehiclesListComponent class VehiclesListComponent_Host 中的错误 - 内联 template:0:0 导致by: 没有 ConnectionBackend 的提供者!
我尝试使用 stack-overflow 搜索解决方案,但发现 HtpModule 应该已经具备正常工作所需的一切。
有人能帮帮我吗?问题出在哪里?
您不能像这样将它添加到提供程序中
providers: [ ApplicationService, InspectionHttpService ]
如果您这样做,那么 Angular 将尝试创建它,并且它不会为 ConnectionBackend
找到提供者
您需要使用一个工厂,您可以在其中传递 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
的能力,如果您需要的话。
更新
在某些环境下,上述代码可能会出错。我忘记了具体的错误信息,但它会给你一个提取工厂函数的建议解决方案,即
export function httpFactory(backend: XHRBackend, options: RequestOptions,
service: ApplicationService) {
return new InspectionHttpService(backend, options, service);
}
useFactory: httpFactory
根据我的记忆,我认为该错误与 AoT 有关
扩展 Http 服务时,必须为父级注入后端和选项 class:
@Injectable()
export class HttpInterceptor extends Http {
constructor(
backend: XHRBackend,
options: RequestOptions,
...
) {
super(backend, options);
}
...
}
这样您就不必使用工厂,因为 Angular 会自行计算注入。
我正在尝试围绕 angular 2 中的内置 Http 服务制作一个包装器,以便有可能添加自定义行为(headers、参数等)
所以我创建了一个普通的class(不是服务)并继承自Http。 Class definition
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();
}*/
}
然后我创建了一个继承自此 class 的服务,以便我可以稍后注入它并用于我的目的。
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;
}
}
Service definition
在我尝试在组件中注入创建的服务后,我收到一个错误:
error_handler.js:47 异常:未捕获(承诺):错误:./VehiclesListComponent class VehiclesListComponent_Host 中的错误 - 内联 template:0:0 导致by: 没有 ConnectionBackend 的提供者!
我尝试使用 stack-overflow 搜索解决方案,但发现 HtpModule 应该已经具备正常工作所需的一切。
有人能帮帮我吗?问题出在哪里?
您不能像这样将它添加到提供程序中
providers: [ ApplicationService, InspectionHttpService ]
如果您这样做,那么 Angular 将尝试创建它,并且它不会为 ConnectionBackend
您需要使用一个工厂,您可以在其中传递 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
的能力,如果您需要的话。
更新
在某些环境下,上述代码可能会出错。我忘记了具体的错误信息,但它会给你一个提取工厂函数的建议解决方案,即
export function httpFactory(backend: XHRBackend, options: RequestOptions,
service: ApplicationService) {
return new InspectionHttpService(backend, options, service);
}
useFactory: httpFactory
根据我的记忆,我认为该错误与 AoT 有关
扩展 Http 服务时,必须为父级注入后端和选项 class:
@Injectable()
export class HttpInterceptor extends Http {
constructor(
backend: XHRBackend,
options: RequestOptions,
...
) {
super(backend, options);
}
...
}
这样您就不必使用工厂,因为 Angular 会自行计算注入。