目前我的应用程序有一个数据服务,它向服务器发出 http 请求以获取数据。每个组件都会单独调用此服务以获取所需的数据。
public getHospitals() {
return this._http.get(this.baseUrl + "/hospitals/")
.map(res => res.json())
.map(json => automapper.map(typeof (JSON), Hospital, json));
}
public getClinics() {
return this._http.get(this.baseUrl + "/clinics/")
.map(res => res.json())
.map(json => automapper.map(typeof (JSON), Clinic, json));
}
当我加载我的示例页面时,我有一个医院组件和一个诊所组件。这两个组件调用数据服务中的相应方法。
我最近扩展了服务器以允许指定它需要什么数据的单个请求。下面是如何调用的示例。
public getLocalData(body) {
const headers = new Headers({ "Content-Type": "application/json" });
const options = new RequestOptions({ headers });
return this._http.post(this.baseUrl, JSON.stringify(body), options)
.map(res => res.json());
}
public getHospitals() {
return this.getLocalData(["Hospitals"])
.map(json => automapper.map(typeof (JSON), Hospital, json.Hospitals));
}
public getClinics() {
return this.getLocalData(["Clinics"])
.map(json => automapper.map(typeof (JSON), Clinic, json.Clinics));
}
这可以改为这样调用,它将返回所有数据:const localData = this.getLocalData(["Hospitals", "Clinics"]);
我的问题是,如何修改这两个组件来为 getLocalData
方法构建主体参数并只发出一个 http 请求?
编辑:我也希望对其进行扩展,以便最终我可以说 10 多个组件,每个组件都有自己的一组本地数据来请求。
最佳答案
一旦您的服务被调用以获取数据,您可以等到所有 ngZone
微任务完成(包括可能对该服务发出的任何其他请求),然后触发单个 http
请求。您需要修改 getLocalData
方法以返回 rxjs
Subject
并且一旦数据从服务器返回,您就可以发出有关主题的数据这样它们就可以传回给适当的调用者。
免责声明我不完全确定这是否是解决此问题的最佳方法,但上述方法应该有效。
这里是修改后的服务和getLocalData
方法。
import {Observable} from "rxjs/Observable";
import "rxjs/add/operator/map";
import "rxjs/add/operator/first";
import {Subject} from "rxjs/Subject";
// ...
public getHospitals() {
return this.getLocalData("Hospitals")
.map(json => automapper.map(typeof (JSON), Hospital, json.Hospitals));
}
public getClinics() {
return this.getLocalData("Clinics")
.map(json => automapper.map(typeof (JSON), Clinic, json.Clinics));
}
private requests = {};
private isAggregating = false;
private getLocalData(dataKey): Subject {
this.requests[dataKey] = this.requests[dataKey] || new Subject();
if(!this.isAggregating){
this.isAggregating = true;
this.ngZone.onMicrotaskEmpty.first().subscribe(() => {
var requests = this.requests;
this.requests = {};
this.isAggregating = false;
const headers = new Headers({ "Content-Type": "application/json" });
const options = new RequestOptions({ headers });
this._http.post(this.baseUrl, JSON.stringify(Object.keys(requests)), options)
.map(res => {
return res.json();
}).subscribe((data) => {
Object.keys(data)
.filter((key) => requests[key])
.forEach((key)=>{
requests[key].next(data[key]);
requests[key].complete();
});
});
});
}
return this.requests[dataKey];
我不确定如何重写它,以便各个服务方法可以请求多组数据,如您的问题所示,但我确信有一种方法可以使用 requests
进行创建映射以启用请求多个集而不是单个集。
Demo
关于angular - 让多个组件构建一个 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42788909/