Angular 6 次依赖服务调用
Angular 6 dependent service calls
我想这个问题以前有人问过,我尝试了我能找到的每一个解决方案,但都无济于事。
我对 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,但无法使它们适应我的特定情况(事实上,第一次调用 returns 一个数组,我需要为每个元素进行第二次调用数组)。
这应该有效(因为你使用了 "angular6" 标签,我假设 rxjs 6):
this._configurationService.getSessionsByCampaign(this.campaignDBID).pipe(
mergeMap(sessionsArray => from(sessionsArray)),
mergeMap(session =>
this._configurationService.getDNByDBID(session.origDNDBID.value)
)
)
因此,首先调用 getSessionsByCampaign 函数,returns 一个会话数组的 Observable。我们通过两个 mergeMap 运算符管道观察:
第一个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
)
我想这个问题以前有人问过,我尝试了我能找到的每一个解决方案,但都无济于事。 我对 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,但无法使它们适应我的特定情况(事实上,第一次调用 returns 一个数组,我需要为每个元素进行第二次调用数组)。
这应该有效(因为你使用了 "angular6" 标签,我假设 rxjs 6):
this._configurationService.getSessionsByCampaign(this.campaignDBID).pipe(
mergeMap(sessionsArray => from(sessionsArray)),
mergeMap(session =>
this._configurationService.getDNByDBID(session.origDNDBID.value)
)
)
因此,首先调用 getSessionsByCampaign 函数,returns 一个会话数组的 Observable。我们通过两个 mergeMap 运算符管道观察:
第一个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
)