我有一个调用http的组件来获取对象(用户)的集合。对于每个用户,我需要进行另一个单独的http调用以获取用户的其他详细信息。如何使用RxJS和observables执行此操作?在这个插件中显示的行为,我们获取github用户列表,然后尝试检索他们的每个关注者以获得关注者数。
订阅代码位于user-grid.component.ts。
http://plnkr.co/edit/Xuu5jqeKVmbY5qwHLJJt
ngOnInit(){
this.users$ = this._githubUserService.getUsers()
.map((res) => res.json())
.flatMap((users) => Observable.from(users))
.flatMap((e) => {
return this._githubUserService.getFollowers(e.followers_url)
.map((followers)=> followers.json())
}, (e, res) => e.followers = res)
}
答案 0 :(得分:1)
我对异步管道并不十分熟悉,但似乎问题是*ngFor
将Observable
中的每个新值视为列表的补液。传递给flatMap
的第二个函数是返回从跟随者调用返回的数组(顺便说一下,为什么它似乎也闪烁,因为每次新请求解析时它都会重建列表)。 / p>
我认为如果你将toArray
运算符附加到结尾,等待所有值都返回。
此外,由于您要将followers
解析为数组,因此不需要在嵌套的h4上使用异步管道。
见这里:
http://plnkr.co/edit/X2OjHGiPpmml2cmLD1tm?p=preview
有趣的一点:
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/toArray';
ngOnInit(){
this.users$ = this._githubUserService.getUsers()
.map((res) => res.json())
.flatMap(users => users)
.flatMap(
(e) => this._githubUserService.getFollowers(e.followers_url),
(e, res) => Object.assign(e, {followers: res.json()}))
.toArray();
}
// in user-grid.component.html
<md-list>
<h1 md-header>GitHub Users</h1>
<md-list-item *ngFor="let user of users$ | async">
<a href="https://github.com/{{user.login}}" target="_new">
<img md-list-avatar [src]="user.avatar_url">
</a>
<h4>{{user.login}} (followers: {{user.followers.length}})</h4>
</md-list-item>
</md-list>
答案 1 :(得分:0)
我无法打开你的plnkr(它让我返回403 - 禁止),但我认为如果你想建立一个这样的结构:
[{ userId: 1, followersQtt : 25 }, { userId: 2, followersQtt : 18 }, ... ]
你可以这样做:
//get the users' json as an Array
let usersJsonArray = this._githubUserService.getUsers().map((res) => res.json());
this.users$ = Observable.from(usersJsonArray) //we have to convert the Array to an Observable
.flatMap((user) => {
//get the followers' json
let followersJsonArray = this._githubUserService.getFollowers(user.followers_url).map((res) => res.json());
return Observable.from(followersJsonArray) //again, we have to convert the Array to an Observable
.map(() => 1) //map each follower to the number 1
.reduce((x,y) => x+y) //sums up all the followers (that were mapped to the number '1')
.map((followersQtt) => { userId : user.id, followersQtt : followersQtt }) //return an object with the informations (I don't know if the user's id is really in the property user.id)
});