Saya suka ide untuk menimpa opsi default, ini sepertinya solusi yang bagus.
Namun, jika Anda ingin memperluas Http
kelas. Pastikan untuk membaca ini sampai selesai!
Beberapa jawaban di sini sebenarnya menunjukkan kelebihan request()
metode yang tidak benar , yang dapat menyebabkan kesalahan yang sulit ditangkap dan perilaku aneh. Saya sendiri telah menemukan ini.
Solusi ini didasarkan pada request()
implementasi metode di Angular 4.2.x
, tetapi harus kompatibel di masa depan:
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;
}
}
Perhatikan bahwa saya mengimpor kelas asli dengan cara ini import { Http as NgHttp } from '@angular/http';
untuk mencegah bentrokan nama.
Masalah yang dibahas di sini adalah bahwa request()
metode memiliki dua tanda tangan panggilan yang berbeda. Saat Request
objek dilewatkan alih-alih URL string
, options
argumen diabaikan oleh Angular. Jadi kedua kasus harus ditangani dengan benar.
Dan inilah contoh cara mendaftarkan kelas yang diganti ini dengan wadah 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
);
}
Dengan pendekatan seperti itu Anda bisa menyuntikkan Http
kelas secara normal, tetapi kelas yang diganti Anda akan disuntikkan secara ajaib. Ini memungkinkan Anda untuk mengintegrasikan solusi Anda dengan mudah tanpa mengubah bagian lain dari aplikasi (polimorfisme sedang bekerja).
Cukup tambahkan httpProvider
ke providers
properti metadata modul Anda.