2016-04-18 12 views
5

sto ottenendo il seguente errore:angolare 2 AsynPipe non funziona con un'osservabile

EXCEPTION: Cannot find a differ supporting object '[object Object]' in [files | async in [email protected]:9] 

Ecco la parte rilevante del modello:

<img *ngFor="#file of files | async" [src]="file.path"> 

Ecco il mio codice:

export class Images { 
    public files: any; 
    public currentPage: number = 0; 
    private _rawFiles: any; 

    constructor(public imagesData: ImagesData) { 
    this.imagesData = imagesData; 
    this._rawFiles = this.imagesData.getData() 
     .flatMap(data => Rx.Observable.fromArray(data.files)); 
    this.nextPage(); 
    } 

    nextPage() { 
    let imagesPerPage = 10; 
    this.currentPage += 1; 
    this.files = this._rawFiles 
        .skip((this.currentPage - 1) * imagesPerPage) 
        .take(imagesPerPage); 
    console.log("this.files:", this.files);     
    } 
} 

Il console.log alla fine mostra che è osservabile:

last console.log

this.imagesData.getData() ritorno un regolare RxJS osservabili dal servizio di angolare Http, quindi perché non sarebbe asincrone tubazioni con esso? Forse il modo in cui sto usando flatMap() è sbagliato e rovina qualcosa?

Se provo a iscriversi a questo osservabile così:

this.files = this._rawFiles 
       .skip((this.currentPage - 1) * imagesPerPage) 
       .take(imagesPerPage) 
       .subscribe(file => { 
        console.log("file:", file); 
       }); 

stampa un elenco di oggetti come previsto:

enter image description here

+1

'* ngFor' solo itera su un array, non una serie di eventi quindi il vostro' Observable' ha la necessità di restituire un array invece di una serie di oggetti. –

+0

Mi piacerebbe un 'Observable ' usando l'operatore 'scan'. –

+0

Vedere anche https://github.com/angular/angular/issues/6392 –

risposta

3

Prova con un Observable<File[]> invece:

this.files = this._rawFiles 
     .skip((this.currentPage - 1) * imagesPerPage) 
     .take(imagesPerPage) 
     .map(file => [file]) 
     .startWith([]) 
     .scan((acc,value) => acc.concat(value)) 

Questo non dovrebbe richiedere codice manuale t o subscribe e dovrebbe funzionare perfettamente con il modello attuale.

faccio qualcosa di molto simile in this blog post.

+0

Grazie. Funziona, anche se non è proprio carina. Sto già ricevendo un array dal server e lo converto solo in uno stream per poter usare i metodi di utilità di RxJS ('skip' e' take'). Se devo convertire in array ogni volta in quel modo, sarebbe più facile non usare RxJS per la manipolazione degli array del tutto –