Angular2-多个相互依赖的http请求 [英] Angular2 - Multiple http requests that depend on each other

查看:45
本文介绍了Angular2-多个相互依赖的http请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在通过重新创建我们在工作中开发的应用程序来学习angular2.该应用程序的一部分需要进行多个http调用.每个呼叫取决于上一个呼叫的结果.我希望第二个,第三个电话等使用上一个电话的结果中的ID.

I am currently learning angular2 by recreating an app that we developed at work. Part of the app needs to make multiple http calls. Each call is dependent on the results from the previous call. I want the second, third call etc to use the id from the result of the previous call.

我的组件代码和服务代码如下

My component code and service code is as follows

组件:

import {Component, OnInit} from '@angular/core';
import {VillageService} from './village.service';

@Component({
    selector: 'village',
    templateUrl: 'app/village/village.component.html',
    styleUrls: ['assets/stylesheets/styles.css'],
    providers: [VillageService]
})

export class VillageComponent implements OnInit {
    villages = [];
    workAreas = [];
    shifts = [];
    roles = [];

    constructor(private _villageService: VillageService){
    }

    ngOnInit() {
        this._villageService.GetAllVillages()
        .subscribe(res => {
            this.villages = res;
        },
        null,
        () => { 
            //Get all work areas for each village
            for(let i = 0; i < this.villages.length; i++){
            this._villageService.GetAllWorkAreas(this.villages[i].VillageId)
                .subscribe(res => {
                    this.workAreas = res;
                },
                null,
                () => { 
                     //Get all shifts for each work area
                    for(let j = 0; j < this.workAreas.length; j++){
                        this._villageService.GetAllShifts(this.workAreas[j].WorkAreaId)
                        .subscribe(res => {
                            this.shifts = res;
                        },
                        null,
                        () => { 
                            //Get all roles for each shift
                            for(let k = 0; k < this.shifts.length; k++){
                               this._villageService.GetAllRoles(this.shifts[k].ShiftId)
                                .subscribe(res => {
                                    this.roles = res;
                                },
                                null,
                                () => { 
                                    this.shifts[k].roles = this.roles;
                                });
                            }  
                            this.workAreas[j].shifts = this.shifts;
                        });
                    }  
                    this.villages[i].workAreas = this.workAreas;
                    console.log(this.villages[i]); 
                });
            }
        });
    }
}

服务:

import { Injectable }     from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';

@Injectable()
export class VillageService {
    private _baseUrl = "{BASE_URL_ADDRESS_GOES_HERE}";

    constructor(private _http: Http){}

    GetAllVillages() {
        return this._http.get(this._baseUrl + "village/All").map(res =>     res.json());
    }

    GetAllWorkAreas(villageId) {
        return this._http.get(this._baseUrl + "WorkArea/All/" +   villageId).map(res => res.json());
    }

    GetAllShifts(workAreaId) {
        return this._http.get(this._baseUrl + "Shift/All/" + workAreaId).map(res => res.json());
    }

    GetAllRoles(shiftId) {
        return this._http.get(this._baseUrl + "Role/All/" + shiftId).map(res => res.json());
    }
}

该代码部分起作用.我得到了所有村庄各自的工作区域;但是,只有最后一个村庄和工作区域具有转移和作用.猜测我的逻辑有问题,但看不到它是什么.我也不喜欢执行多个循环,但想不出另一种方法来完成此操作.

The code partially works. I get all villages with their respective work areas; however, only the last village and work area has its shifts and roles. Guessing there is something wrong in my logic but can't see what it is. I also don't like doing multiple loops but couldn't think of another way to do this.

有人知道如何做得更好吗?我尝试调试以查看发生了什么,但是一直陷入循环地狱.

Does anyone have an idea of how to do this better? I have tried debugging to see what is happening but keep getting caught in loop hell.

先谢谢了.感谢您的帮助.

Thanks in advance. Any help is appreciated.

推荐答案

在不讨论代码细节的情况下,当您使用这种结构(call1 => call2 => call3)时应使用的运算符一个调用用于另一个调用的是mergeMap(rxjs中的flatmap的别名).看起来有点像这样.

Without going into the details of your code, the operator that you should be using when you such a structure (call1 => call2 => call3) where the result of one call is used for another is mergeMap (alias for flatmap in rxjs). This would look a little like this.

this._villageService.GetAllVillages()
    .flatMap(
       (response) => {
         // take from the response what you want and use it for the next call
         this._villageService.GetAllWorkAreas(//pass the thing from your previous response here)
       }
    )
    .flatMap(
      ....
    )
    .subscribe(...)

对于每个相关调用,根据需要重复此flatMap.

Repeat this flatMap as much as needed, for every dependent call.

flatMap的作用是,它对每个值执行一个函数,并期望该函数返回一个可观察的对象.在幕后,它将订阅该可观察对象,并且一旦有了其值,便会将其发送到下一个平面图.

What flatMap does is, it performs a function on every value, and expects that function to return an observable. Under the covers it will subscribe to that observable, and once it has a value, it will send it to the next flatmap.

因此,首先您获得了所有村庄.如果您具有此值,它将被发送到第一个flatMap.第一个,将执行另一个请求.该请求完成后,结果将传递到下一个flatMap,依此类推...

So, first you get all the villages. If you have this value, it will be send to the first flatMap. The first one, will perform another request. Once that request completes, the result will be past to the next flatMap and so on...

这篇关于Angular2-多个相互依赖的http请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆