Tôi thích ý tưởng ghi đè các tùy chọn mặc định, đây có vẻ là một giải pháp tốt.
Tuy nhiên, nếu bạn đang mở rộng Http
lớp học. Hãy chắc chắn để đọc điều này thông qua!
Một số câu trả lời ở đây thực sự cho thấy quá tải request()
phương pháp không chính xác , điều này có thể dẫn đến một lỗi khó bắt và hành vi kỳ lạ. Tôi đã vấp phải điều này bản thân mình.
Giải pháp này dựa trên request()
việc triển khai phương pháp trong Angular 4.2.x
, nhưng phải tương thích với tương lai:
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;
}
}
Lưu ý rằng tôi đang nhập lớp gốc theo cách này import { Http as NgHttp } from '@angular/http';
để ngăn chặn xung đột tên.
Vấn đề được giải quyết ở đây là request()
phương pháp này có hai chữ ký cuộc gọi khác nhau. Khi Request
đối tượng được thông qua thay vì URL string
, options
đối số bị bỏ qua bởi Angular. Vì vậy, cả hai trường hợp phải được xử lý đúng.
Và đây là ví dụ về cách đăng ký lớp bị ghi đè này với DI container:
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
);
}
Với cách tiếp cận như vậy bạn có thể tiêm Http
lớp bình thường, nhưng lớp bị ghi đè của bạn sẽ được tiêm một cách kỳ diệu thay vào đó. Điều này cho phép bạn tích hợp giải pháp của mình một cách dễ dàng mà không thay đổi các phần khác của ứng dụng (tính đa hình trong hành động).
Chỉ cần thêm httpProvider
vào thuộc providers
tính của siêu dữ liệu mô-đun của bạn.