2016-01-07 27 views
8

Tôi đang cố gắng sử dụng http của GET Angular 2 để lấy danh sách các bài viết hàng đầu về HackerNews và sau đó tôi sẽ lấy lại các chi tiết tương ứng của chúng trong lồng nhau có thể quan sát được.Lồng nhau quan sát được trong Angular 2

Tôi gặp lỗi này khi cố gắng lặp và hiển thị dữ liệu trong HTML của mình.

Không thể tìm thấy một khác nhau hỗ trợ đối tượng '[đối tượng Object]

Cannot find a differ supporting object '[object Object]'

Ngoài ra, tôi đoán có phải là một cách tốt hơn để làm điều này, bất kỳ con trỏ?

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> 

Trả lời

5

Tôi không nghĩ rằng đó là một thực hành tốt để tổ XHR thể quan sát được gọi ... nhưng tôi không phải là một chuyên gia về nó và không thể cho bạn biết lý do tại sao bạn có ngoại lệ này (có thể là về điều này that var ..).

Nhưng tôi có một cách tiếp cận khác nhau để cho bạn thấy:

Một thành phần <top-stories> tải danh sách id đầu tiên và sau đó tạo ra những người khác thành phần <top-story> cho mỗi người:

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

Thành phần <top-story> tải tự đăng chi tiết và hiển thị nó:

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

Bạn có thể chơi với nó trong máy xếp này: http://plnkr.co/edit/BRMlyD?p=preview

+0

nhưng tại sao không phải là một thực hành tốt để lồng họ? Tôi có một vấn đề bởi vì tôi đang làm tổ để http.get trả lại hai quan sát được, tôi đang cố gắng để có một cái gì đó như lời hứa (giải quyết cuộc gọi đầu tiên sau đó làm thứ hai) nhưng tôi nhận được một số tham số không xác định như tôi đang ở trong phạm vi khác . – mautrok

+0

Tôi không thực sự nghĩ rằng nó xấu để tổ chức các cuộc gọi xhr quan sát nhưng những gì là xấu là để làm tổ đăng ký (đăng ký một quan sát bên trong một thuê bao quan sát được). Bạn phải sử dụng toán tử như 'flatMap',' concatMap', .. và chỉ đăng ký một lần. – bertrandg

16

Tôi nghĩ rằng bạn có thể viết lại nó trong một cách hơn Rx-ish như thế này:

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()) 
} 
Các vấn đề liên quan