如何在Angular2中进行嵌套的Observable调用 [英] How to make nested Observable calls in Angular2

查看:56
本文介绍了如何在Angular2中进行嵌套的Observable调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在进行嵌套的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的运算符有所了解.您的示例非常冗长,以不应该使用它们的方式使用flatMapmap.同样,您的第一个示例也不起作用,因为您没有订阅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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆