我喜欢覆盖默认选项的想法,这似乎是一个不错的解决方案。
但是,如果您打算扩展Http
课程。请务必通读!
这里的一些答案实际上显示了request()
方法的不正确重载,这可能导致难以捕获的错误和奇怪的行为。我自己偶然发现了这个。
此解决方案基于request()
Angular中的方法实现4.2.x
,但应与将来兼容:
import {Observable} from 'rxjs/Observable';
import {Injectable} from '@angular/core';
import {
ConnectionBackend, Headers,
Http as NgHttp,
Request,
RequestOptions,
RequestOptionsArgs,
Response,
XHRBackend
} from '@angular/http';
import {AuthenticationStateService} from '../authentication/authentication-state.service';
@Injectable()
export class Http extends NgHttp {
constructor (
backend: ConnectionBackend,
defaultOptions: RequestOptions,
private authenticationStateService: AuthenticationStateService
) {
super(backend, defaultOptions);
}
request (url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
if ('string' === typeof url) {
url = this.rewriteUrl(url);
options = (options || new RequestOptions());
options.headers = this.updateHeaders(options.headers);
return super.request(url, options);
} else if (url instanceof Request) {
const request = url;
request.url = this.rewriteUrl(request.url);
request.headers = this.updateHeaders(request.headers);
return super.request(request);
} else {
throw new Error('First argument must be a url string or Request instance');
}
}
private rewriteUrl (url: string) {
return environment.backendBaseUrl + url;
}
private updateHeaders (headers?: Headers) {
headers = headers || new Headers();
// Authenticating the request.
if (this.authenticationStateService.isAuthenticated() && !headers.has('Authorization')) {
headers.append('Authorization', 'Bearer ' + this.authenticationStateService.getToken());
}
return headers;
}
}
请注意,我以这种方式导入原始类import { Http as NgHttp } from '@angular/http';
,以防止名称冲突。
此处解决的问题是该request()
方法具有两个不同的调用签名。当Request
传递object而不是URL时string
,options
Angular将忽略该参数。因此,两种情况都必须妥善处理。
这是如何使用DI容器注册此重写的类的示例:
export const httpProvider = {
provide: NgHttp,
useFactory: httpFactory,
deps: [XHRBackend, RequestOptions, AuthenticationStateService]
};
export function httpFactory (
xhrBackend: XHRBackend,
requestOptions: RequestOptions,
authenticationStateService: AuthenticationStateService
): Http {
return new Http(
xhrBackend,
requestOptions,
authenticationStateService
);
}
通过这种方法,您可以Http
正常地注入类,但是您替代的类将被神奇地注入。这使您可以轻松集成解决方案,而无需更改应用程序的其他部分(实际中的多态性)。
只需添加httpProvider
到providers
模块元数据的属性即可。