Angular 角度2的嵌套可观测

Angular 角度2的嵌套可观测,angular,rxjs,Angular,Rxjs,我正在尝试Angular 2的http GET来检索HackerNews上的顶级文章列表,之后我将在嵌套的observable中检索它们各自的详细信息 我在尝试循环并在HTML中显示数据时遇到了这个错误 找不到不同的支持对象“[object]” 还有,我猜应该有更好的方法来做到这一点,有指针吗 getTopPost() { this.http.get('https://hacker-news.firebaseio.com/v0/topstories.json') .map(

我正在尝试Angular 2的http GET来检索HackerNews上的顶级文章列表,之后我将在嵌套的observable中检索它们各自的详细信息

我在尝试循环并在HTML中显示数据时遇到了这个错误

找不到不同的支持对象“[object]”

还有,我猜应该有更好的方法来做到这一点,有指针吗

getTopPost() {
    this.http.get('https://hacker-news.firebaseio.com/v0/topstories.json')
      .map(res => res.json())
      .subscribe(
        data => { 
                    data.map(function(postId){
                            let storyUrl = "https://hacker-news.firebaseio.com/v0/item/"+ postId +".json";
                            that.http.get(storyUrl)
                                .map(res => res.json())
                                .subscribe(data => that.hnData = data, 
                                           err => that.logError(err),
                                           () => console.log(that.hnData));

                        });

                },
        err => this.logError(err);
      );

  }
HTML


{{item.title}

我认为嵌套可观察的xhr调用不是一个好的做法。。。但我不是这方面的专家,也不能告诉你为什么会出现这个异常(可能是关于这个
那个
var…)

但我有一个不同的方法向你们展示:

第一个组件加载id列表,然后为每个组件生成其他组件:

@Component({
  selector: 'top-stories',
  providers: [],
  template: '
    <div>
      <h2>Hacker news top stories:</h2>
      <ul>
        <li top-story *ngFor="#story; #i = index of list | async" [num]="i+1" [id]="story"></li>
      </ul>
    </div>
  ',
  directives: [TopStory]
})
export class TopStories {
  list: Observable<Array<number>>;

  constructor(private http: Http) {
    this.list = this.http.get('https://hacker-news.firebaseio.com/v0/topstories.json')
    .map(res => res.json())
    .map(list => list.slice(0, 30));
  }
}
@组件({
选择器:“顶级故事”,
提供者:[],
模板:'
黑客新闻头条:
', 指令:[托普斯托里] }) 出口级上托利面{ 列表:可观察 加载。。。 `, 指令:[] }) 导出类TopStory实现OnInit、OnDestroy{ @Input()num:数字; @Input()id:Number; 分:任何; 项目:对象; 构造函数(私有http:http){} 恩戈尼尼特(){ this.sub=this.http.get('https://hacker-news.firebaseio.com/v0/item/“+this.id+”.json') .map(res=>res.json()) .subscribe(item=>this.item=item); } 恩贡德斯特罗(){ 此.sub.取消订阅(); } }
您可以在这个plunker中玩它:

我想你可以用一种更像Rx的方式重写它,如下所示:

getTopPost() {
  return http.get('https://hacker-news.firebaseio.com/v0/topstories.json')
    .map(res => res.json())
    .mergeMap(list => Observable.fromArray(list))
    .mergeMap(postId => http.get("https://hacker-news.firebaseio.com/v0/item/"+ postId +".json"))
    .map(res => res.json())
}

但是为什么嵌套它们不是一个好的实践呢?我遇到了一个问题,因为我正在嵌套到http。如果返回两个可观察的,我会尝试使用类似于promise(解析第一个调用,然后执行第二个调用)的东西,但是我得到了一些未定义的参数,就像我在另一个作用域中一样。我真的认为嵌套可观察的xhr调用不好,但不好的是嵌套订阅(在另一个可观察订阅中订阅一个可观察订阅)。您必须使用诸如
flatMap
concatMap
,…之类的运算符,并且只订阅一次。
@Component({
  selector: '[top-story]',
  providers: [],
  template: `
    <div>
      <a *ngIf="item" [href]="item?.url">{{ num + ': ' + item?.title }}</a>
      <span *ngIf="!item">loading...</span>
    </div>
  `,
  directives: []
})
export class TopStory implements OnInit, OnDestroy {
  @Input() num: Number;
  @Input() id: Number;

  sub: any;
  item: object;

  constructor(private http: Http) {}

  ngOnInit() {
    this.sub = this.http.get('https://hacker-news.firebaseio.com/v0/item/' + this.id + '.json')
    .map(res => res.json())
    .subscribe(item => this.item = item);
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }
}
getTopPost() {
  return http.get('https://hacker-news.firebaseio.com/v0/topstories.json')
    .map(res => res.json())
    .mergeMap(list => Observable.fromArray(list))
    .mergeMap(postId => http.get("https://hacker-news.firebaseio.com/v0/item/"+ postId +".json"))
    .map(res => res.json())
}