Мені подобається ідея змінити параметри за замовчуванням, це здається хорошим рішенням.
Однак якщо ви до розширення 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об'єкт передається замість 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властивості метаданих вашого модуля.