首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用TypeScript从Angular2中的http数据链接RxJS观察值

用TypeScript从Angular2中的http数据链接RxJS观察值
EN

Stack Overflow用户
提问于 2016-02-08 19:24:08
回答 2查看 71.7K关注 0票数 102

在过去的4年里,我一直在愉快地使用AngularJS 1.*,现在我正在尝试自学Angular2和TypeScript!我不得不承认我讨厌它,但我确信我的灵感时刻就在眼前……无论如何,我已经在我的虚拟应用程序中编写了一个服务,它将从我编写的服务于JSON的虚假后端获取http数据。

代码语言:javascript
复制
import {Injectable} from 'angular2/core';
import {Http, Headers, Response} from 'angular2/http';
import {Observable} from 'rxjs';

@Injectable()
export class UserData {

    constructor(public http: Http) {
    }

    getUserStatus(): any {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this.http.get('/restservice/userstatus', {headers: headers})
            .map((data: any) => data.json())
            .catch(this.handleError);
    }

    getUserInfo(): any {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this.http.get('/restservice/profile/info', {headers: headers})
            .map((data: any) => data.json())
            .catch(this.handleError);
    }

    getUserPhotos(myId): any {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        return this.http.get(`restservice/profile/pictures/overview/${ myId }`, {headers: headers})
            .map((data: any) => data.json())
            .catch(this.handleError);
    }

    private handleError(error: Response) {
        // just logging to the console for now...
        console.error(error);
        return Observable.throw(error.json().error || 'Server error');
    }   
}

现在,在一个组件中,我希望同时运行(或链接) getUserInfo()getUserPhotos(myId)方法。在AngularJS中,这很简单,因为在我的控制器中,我会这样做,以避免“末日金字塔”……

代码语言:javascript
复制
// Good old AngularJS 1.*
UserData.getUserInfo().then(function(resp) {
    return UserData.getUserPhotos(resp.UserId);
}).then(function (resp) {
    // do more stuff...
}); 

现在我已经尝试在我的组件中做类似的事情(用.subscribe替换.then ),但是我的错误控制台变得疯狂了!

代码语言:javascript
复制
@Component({
    selector: 'profile',
    template: require('app/components/profile/profile.html'),
    providers: [],
    directives: [],
    pipes: []
})
export class Profile implements OnInit {

    userPhotos: any;
    userInfo: any;

    // UserData is my service
    constructor(private userData: UserData) {
    }

    ngOnInit() {

        // I need to pass my own ID here...
        this.userData.getUserPhotos('123456') // ToDo: Get this from parent or UserData Service
            .subscribe(
            (data) => {
                this.userPhotos = data;
            }
        ).getUserInfo().subscribe(
            (data) => {
                this.userInfo = data;
            });
    }

}

很明显我做错了什么。我怎样才能最好地使用可观察性和RxJS?抱歉,如果我问了一些愚蠢的问题...不过,还是要提前感谢你的帮助!在声明http头文件时,我也注意到了函数中的重复代码。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-08 19:29:45

对于您的用例,我认为flatMap操作符是您需要的:

代码语言:javascript
复制
this.userData.getUserPhotos('123456').flatMap(data => {
  this.userPhotos = data;
  return this.userData.getUserInfo();
}).subscribe(data => {
  this.userInfo = data;
});

这样,您将在收到第一个请求后执行第二个请求。当您想要使用前一个请求(前一个事件)的结果来执行另一个请求时,flatMap操作符特别有用。不要忘记导入运算符才能使用它:

代码语言:javascript
复制
import 'rxjs/add/operator/flatMap';

此答案可以提供更多详细信息:

如果你只想使用subscribe方法,你可以使用类似这样的方法:

代码语言:javascript
复制
this.userData.getUserPhotos('123456')
    .subscribe(
      (data) => {
        this.userPhotos = data;

        this.userData.getUserInfo().subscribe(
          (data) => {
            this.userInfo = data;
          });
      });

最后,如果你想并行执行这两个请求,并在所有结果都出来时得到通知,你应该考虑使用Observable.forkJoin (你需要添加import 'rxjs/add/observable/forkJoin'):

代码语言:javascript
复制
Observable.forkJoin([
  this.userData.getUserPhotos(),
  this.userData.getUserInfo()]).subscribe(t=> {
    var firstResult = t[0];
    var secondResult = t[1];
});
票数 150
EN

Stack Overflow用户

发布于 2021-08-16 15:39:44

您实际需要的是switchMap操作符。它获取初始数据流(用户信息),当完成时,将其替换为可观察到的图像。

我是这样理解你的流程的:

  • 获取用户信息
  • 从该信息获取用户Id
  • 使用用户Id获取用户照片

Here is a demo。注意:我模拟了服务,但代码将与真正的服务一起工作。

代码语言:javascript
复制
  ngOnInit() {
    this.getPhotos().subscribe();
  }

  getUserInfo() {
    return this.userData.getUserInfo().pipe(
      tap(data => {
        this.userInfo = data;
      }))
  }
  getPhotos() {
    return this.getUserInfo().pipe(
      switchMap(data => {
        return this.userData.getUserPhotos(data.UserId).pipe(
          tap(data => {
            this.userPhotos = data;
          })
        );
      })
    );
  }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35268482

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档