【问题标题】:Angular 6 dependent service callsAngular 6 依赖服务调用
【发布时间】:2018-11-18 00:40:58
【问题描述】:

我想这个问题以前有人问过,我尝试了所有能找到的解决方案,但都无济于事。 我对 RxJs 有点陌生,如果这看起来很简单,我深表歉意。

考虑以下服务:

getSessionsByCampaign(campaignDBID: number) : Observable<CfgCampaignGroup[]>{
    return this.http.get<CfgCampaignGroup[]>('http://localhost:4567/api/configuration/sessions?campaign=' + campaignDBID);
}

getDNByDBID(dnDBID: number): Observable<CfgDN[]>{
    return this.http.get<CfgDN[]>('http://localhost:4567/api/configuration/dns?dbid=' + dnDBID);
}

我有一个组件需要:

  • 获取getSessionsByCampaign的结果
  • 然后,对于返回的每个元素,调用 getDNByDBID(从元素中传递一个值)

我得到的最接近的是:

this._configurationService.getSessionsByCampaign(this.campaignDBID).subscribe(dialingSessionsList => {
  this.dialingSessions = dialingSessionsList;
   dialingSessionsList.forEach((e) => {
    this._configurationService.getDNByDBID(e["CfgCampaignGroup"].origDNDBID.value).subscribe(dn => this.dns.push(dn[0]));
  }) 
});

但显然,当我尝试在我的组件模板中使用 this.dns 时,它是未定义的...

我查看了 mergeMap、switchMap 和 forkJoin,但无法使它们适应我的特定情况(事实上第一次调用返回一个数组,而我需要对数组的每个元素进行第二次调用)。

【问题讨论】:

    标签: typescript rxjs angular6


    【解决方案1】:

    这应该可以工作(因为你使用了“angular6”标签,我假设 rxjs 6):

    this._configurationService.getSessionsByCampaign(this.campaignDBID).pipe(
        mergeMap(sessionsArray => from(sessionsArray)),
        mergeMap(session => 
           this._configurationService.getDNByDBID(session.origDNDBID.value)
        )
    )
    

    因此,首先调用 getSessionsByCampaign 函数,该函数返回会话数组的 Observable。我们通过两个 mergeMap 操作符来传递 observable:

    第一个 mergeMap 调用 'from' 运算符,它将数组的 Observable 转换为 Observable 的数组。

    第二个 mergeMap 对数组中每个 Observable 的值调用 getDNByDBID 函数。

    这将依次发出每个结果。

    如果你想发出一个带有结果数组的可观察对象,请将 toArray() 添加到管道的末尾,如下所示:

    this._configurationService.getSessionsByCampaign(this.campaignDBID).pipe(
        mergeMap(sessionsArray => from(sessionsArray)),
        mergeMap(session => 
           this._configurationService.getDNByDBID(session.origDNDBID.value)
        ),
        toArray()
    )
    

    您的导入将是:

    import {from} from 'rxjs';
    import {mergeMap, toArray} from 'rxjs/operators';
    

    编辑:订阅后看起来像这样:

    this._configurationService.getSessionsByCampaign(this.campaignDBID).pipe(
        mergeMap(sessionsArray => from(sessionsArray)),
        mergeMap(session => 
           this._configurationService.getDNByDBID(session.origDNDBID.value)
        ),
        toArray()
    ).subscribe(
        dnArray => this.dns = dnArray,
        err => this.console.error(err); // or other, better error-handling
    )
    

    【讨论】:

    • 感谢@GreyBeardedGeek。虽然我确实理解了解释(并且您刚刚向我解释了地图),但我如何在模板中使用生成的 Observable?
    猜你喜欢
    • 2019-03-04
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    相关资源
    最近更新 更多