2016-01-07 162 views
8

我正在嘗試Angular 2的http GET來檢索HackerNews上的頂級文章列表,之後我將在嵌套的observable中檢索它們各自的細節。Angular 2中的嵌套Observable

我試圖循環顯示HTML中的數據時遇到此錯誤。

無法找到一個不同的支持對象「的翻譯:」

Cannot find a differ supporting object '[object 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

<ion-item *ngFor="#item of hnData"> 
     {{item.title}} 
</ion-item> 

回答

5

我不認爲這是一個很好的做法,巢觀察到XHR調用......但我不是一個關於它的專家,不能告訴你爲什麼你有這個例外(可能是關於這個that var ..)。

但我有不同的方法來告訴你:

第一分量<top-stories>負載ID列表,然後生成其他組件<top-story>爲每一位:

@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)); 
    } 
} 

組件<top-story>負載本身發佈細節並顯示它:

@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(); 
    } 
} 

你可以在這個運動中玩它: http://plnkr.co/edit/BRMlyD?p=preview

+0

但爲什麼不是一個好的做法,以嵌套的呢?我有一個問題,因爲我嵌套到http.get返回兩個可觀察的,我想它有像承諾(解決第一次調用,然後做第二次),但我得到一些未定義的參數,如我在另一個範圍。 – mautrok

+0

我真的不認爲嵌套可觀察的xhr調用是不好的,但不好的是嵌套訂閱(訂閱另一個可觀察訂閱內的觀察值)。你必須使用'flatMap','concatMap'等操作符,並且只需一次訂閱它。 – bertrandg

16

我覺得你可以在一個更RX-ISH方式像這樣把它改寫:

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()) 
}