如何在Angular2中进行嵌套的Observable调用 [英] How to make nested Observable calls in Angular2
问题描述
我在进行嵌套的Observable调用时遇到了一些麻烦.我的意思是对http服务的调用,该服务检索一个用户,然后从该用户获取ID以进行另一个http调用,最后将结果呈现在屏幕上.
I am having some troubles making nested Observable calls. By that I mean a call to a http service that retrieve a user, then getting the id from the user to make another http call, and finally render the results on screen.
1)HTTP GET 1:获取用户
1) HTTP GET 1 : get the User
2)HTTP GET 2:通过传递唯一标识符作为参数来获取用户的首选项
2) HTTP GET 2: get the User's preferences passing a unique identifier as a parameter
这将转换为组件Blah.ts
中的以下代码:
This translates into the following code in component Blah.ts
:
版本1 -此代码不显示任何内容
version 1 - this code does not display anything
ngOnInit() {
this.userService.getUser()
.flatMap(u => {
this.user = u; // save the user
return Observable.of(u); // pass on the Observable
})
.flatMap(u => this.userService.getPreferences(this.user.username)) // get the preferences for this user
.map(p => {
this.preferences = p; // save the preferences
});
}
版本2 -此代码有效,但对我来说似乎是错误的方法:
version 2 - this code works but seems the wrong approach to me:
this.userService.getUser().subscribe(u => {
this.user = u;
this.userService.getPreferences(this.user.username).subscribe(prefs => {
this.preferences = prefs;
});
});
这是模板:
<h3>User</h3>
<div class="row col-md-12">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">User details</h3>
</div>
<div class="panel-body">
<table class="table table-condensed">
<thead>
<tr>
<th>Username</th>
<th>Full Name</th>
<th>Enabled</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{user?.username}}</td>
<td>{{user?.fullName}}</td>
<td>{{user?.enabled}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- end of col 1-->
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">User preferences</h3>
</div>
<div class="panel-body">
<table class="table table-condensed">
<thead>
<tr>
<th>Language</th>
<th>Locale</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{preferences?.preferences?.get('language')}}</td>
<td>{{preferences?.preferences?.get('locale')}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- end of col 2-->
</div>
<!-- end of row 1-->
我认为显示该服务没有任何意义,只需进行http get()
调用即可,例如:
I don't think there is any point in showing the service, which simply makes http get()
calls like:
http.get('http://blablah/users/')
.map((response) => response.json())
请提出哪种方法是定义可观察对象链的最佳方法.
推荐答案
您应该对rxjs的运算符有所了解.您的示例非常冗长,以不应该使用它们的方式使用flatMap
和map
.同样,您的第一个示例也不起作用,因为您没有订阅Observable.
You should read up on rxjs's operators a little. Your examples are very verbose and use flatMap
and map
in a way they're not supposed to be used. Also your first example can't work, because you're not subscribing to the Observable.
这将满足您的需求:
ngOnInit() {
this.userService.getUser()
.do(u => this.user = u) //.do just invokes the function. does not manipulate the stream, return value is ignored.
.flatMap(u => this.userService.getPreferences(u.username))
.subscribe(p => this.preferences = p);
}
从rxjs 5.5开始,您应该使用管道运算符:
As of rxjs 5.5 you should use the pipeable operators:
ngOnInit() {
this.userService.getUser().pipe(
tap(u => this.user = u),
flatMap(u => this.userService.getPreferences(u.username))
).subscribe(p => this.preferences = p);
}
这篇关于如何在Angular2中进行嵌套的Observable调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!