angular - 让多个组件构建一个 HTTP 请求

标签 angular typescript

目前我的应用程序有一个数据服务,它向服务器发出 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/

相关文章:

通过组件代码进行Angular2 Material 控制

javascript - 无法让 css 应用于 Angular 组件

angular - 你如何处理 material2 卡中带有 mat-card-header-text 的 div?

Angular + Jest : Can't resolve all parameters for AppComponent: (? )

javascript - Typescript 相当于 JS 模块模式

Angular Typescript getter 和 setter 返回未定义

Angular 2 - 在每个 http 请求中附加 withCredentials = true

angular - 使用 Iframe 多次发生 onLoad

angular - NGiNX - 没有为错误返回足够的 header (4xx,5xx)与成功(2xx)

rest - typescript 没有正确推断剩余参数