私はデフォルトのオプションを上書きするアイデアが好きです、これは良い解決策のようです。
ただし、拡張するまでなら 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()
メソッドに2つの異なる呼び出し署名があることです。ときにRequest
オブジェクトが代わりにURLを渡されstring
、options
引数は角度によって無視されます。したがって、両方のケースを適切に処理する必要があります。
そして、このオーバーライドされたクラスを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
です。