我一直在努力从我的http请求序列中获得正确的效果。我必须发出一个返回网站对象数组的初始请求。然后,我必须使用站点对象中找到的两个id来再发出两个http请求,以获取关联的站点组织名称和团队名称,并将它们添加到每个站点对象。所以我的步骤是:
我的代码如下:
private getSites() {
this.spinner.show();
this.sitesService.getSitesByUserId(this.userId)
.subscribe(
_data => {
_data.map(site => {
this.orgService.getOrganization(site['OrganizationId'])
.map(org => {
site['orgName'] = org['org']['name'];
return org;
})
.flatMap(() => this.teamsService.getTeam(site['TeamId']))
.map(team => {
site['teamName'] = team['team']['name'];
return team;
})
.subscribe(
_d => {
this.sites.push(site);
}
);
});
},
_error => {},
() => {
this.spinner.hide();
this.loading = false;
}
);
}
在我的html中,我绑定了数据:
<div *ngFor="let site of (sites | filterlist: value : 'name')">
<card-directory-item (click)="siteSelected(site)">
<i class="material-icons item-icon">location_city</i>
<h2 class="item-name">{{ site.name }}</h2>
<div class="item-field-1">{{ site.city }} {{ site.state }} </div>
<div class="item-static-field flex-column">
<div>{{ site.teamName }}</div>
<div>{{ site.orgName }}</div>
</div>
</card-directory-item>
</div>
问题是在完成所有步骤之前删除了微调器,并且每个列表项在完成的顺序中弹出到位。我知道为什么会这样。在移除微调器并显示数据之前,我只是无法弄清楚如何链接可观察流以完成所有内容。
任何帮助都会很棒。感谢。
答案 0 :(得分:2)
问题是你 python -c "import six; print (six.__version__)"
过早地“subscribe
返回的观察者getSitesByUserId(this.userId)
。
这里你的代码看起来有点像这样
this.sitesService.getSitesByUserId(this.userId)
.subscribe(
otherAsyncOp,
errorCallback,
completeCallback
)
问题是,只要onCompleteCallback
返回的observable已经完成,就会在你的其他http请求完成之前调用getSitesByUserId
。
如果您想依次调用所有网址,则必须使用mergeMap
(或flatMap
这是别名)
this.sitesService.getSitesByUserId(this.userId)
.mergeMap(sites => Rx.Observable.from(sites)) // create an observable per site
.mergeMap(site => this.sitesService.getOrga(site.id)
.map(orga => Object.assign({}, site, { orgName: orga.org.name }))
.mergeMap(site => this.sitesService.getTeam(site.teamId).map(team => Object.assign({}, site, {teamName: team.team.name})
.reduce((sites, site) => sites.concat(site), [])
.subscribe( /* there every request should be done and you can remove your loader */)
对不起,这是一个很长的答案,但你的问题非常广泛。我无法执行该代码,所以我不是100%确定它是否有效,但至少你明白这一点。
答案 1 :(得分:1)
您可以将每个网站映射到组织和团队请求的zip。 zip
的第三个参数是一个可以用Object.assign
组成最终对象的回调。
this.sitesService
.getSitesByUserId(this.userId)
.mergeMap(sites => Observable.from(sites))
.mergeMap(site => {
return Observable.zip(
this.orgService.getOrganization(site['OrganizationId']),
this.teamService.getTeam(site['TeamId']),
(org, team) => Object.assign(site, {
orgName: org['org']['name'],
teamName: team['team']['name']
})
)
})
.subscribe(console.log)