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