ฉันชอบความคิดที่จะแทนที่ตัวเลือกเริ่มต้นดูเหมือนว่าจะเป็นทางออกที่ดี
อย่างไรก็ตามหากคุณกำลังขยายการ Http
คลาสขึ้นไป อย่าลืมอ่านข้อความนี้ด้วย!
บางคำตอบที่นี่แสดงว่ามีการโหลดมากเกินไปที่ไม่ถูกต้อง request()
วิธีการซึ่งอาจนำไปสู่ข้อผิดพลาดที่จับยากและพฤติกรรมแปลก ๆ ฉันพบสิ่งนี้ด้วยตัวเอง
โซลูชันนี้ใช้request()
วิธีการนำไปใช้ในเชิงมุม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
อาร์กิวเมนต์จะถูกละเว้นโดยเชิงมุม ดังนั้นทั้งสองกรณีจะต้องได้รับการจัดการอย่างเหมาะสม
และนี่คือตัวอย่างของการลงทะเบียนคลาสที่ถูกแทนที่ด้วยคอนเทนเนอร์ 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
คลาสปกติ แต่คลาสที่แทนที่ของคุณจะถูกฉีดอย่างน่าอัศจรรย์แทน สิ่งนี้ช่วยให้คุณสามารถรวมโซลูชันของคุณได้อย่างง่ายดายโดยไม่ต้องเปลี่ยนส่วนอื่น ๆ ของแอปพลิเคชัน (polymorphism in action)
เพียงแค่เพิ่มhttpProvider
ไปยังproviders
สถานที่ให้บริการของเมตาดาต้าโมดูลของคุณ