经过更多研究并深入研究 angular2 源代码后,$templateCache in Angular 2? 为我指出了正确的解决方案。我必须通过 provide() 注册一个新的自定义 Http 和一个自定义 XHR 实现:
providers: [HTTP_PROVIDERS,
provide(Http, {
useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) => new HttpInterceptor(xhrBackend, requestOptions),
deps: [XHRBackend, RequestOptions]
}),
provide(XHR, {
useFactory: (http: Http) => new XHRInterceptor(http), deps: [Http]
})],
每次 angular2 通过 Compontent 的 tempateUrl 加载 html 模板时,都会注入 XHRInterceptor(XHR 接口的实现)并在内部使用。因为我们将自定义 Http 实现注入 XHRInterceptor 构造函数并通过 HttpInterceptor 委托所有 get 请求,所以我们可以完全控制来自应用程序的所有 http 请求:
export class XHRInterceptor extends XHR {
constructor(private _http: Http) {
super()
}
get(url: string): Promise<string> {
var completer: PromiseCompleter<string> = PromiseWrapper.completer();
this._http.get(url).map(data=> {
return data.text();
}).subscribe( data => {
completer.resolve(data);
}, error=>{
completer.reject(`Failed to load ${url}`, null);
});
return completer.promise;
}
}
这是我的 HttpInterceptor 类:
export class HttpInterceptor extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
if (typeof url === "string") {
return this.interceptResult(super.request(this.interceptUrl(url), this.interceptOptions(options)));
} else {
return this.interceptResult(super.request(url, this.interceptOptions(options)));
}
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
return this.interceptResult(super.get(this.interceptUrl(url), this.interceptOptions(options)));
}
post(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
return this.interceptResult(super.post(this.interceptUrl(url), body, this.interceptOptions(options)));
}
put(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
return this.interceptResult(super.put(this.interceptUrl(url), body, this.interceptOptions(options)));
}
delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
return this.interceptResult(super.delete(this.interceptUrl(url), this.interceptOptions(options)));
}
interceptUrl(url: string): string {
// Do some stuff with the url....
//...
return url;
}
interceptOptions(options?: RequestOptionsArgs): RequestOptionsArgs {
// prepare options...
if (options == null) {
options = new RequestOptions();
}
if (options.headers == null) {
options.headers = new Headers();
}
// insert some custom headers...
// options.headers.append('Content-Type', 'application/json');
return options;
}
interceptResult(observable: Observable<Response>): Observable<Response> {
// Do some stuff with the result...
// ...
return observable;
}
}