7

Possiedo un componente Angular 2 che utilizza *ngFor per eseguire il rendering di una matrice nidificata di numeri.Come riutilizzare gli elementi di ngPer anche se il riferimento all'elenco cambia?

@Component({ 
    selector: 'app', 
    template: ` 
    <div *ngFor="let row in data"> 
     <div *ngFor="let curve in row"> 
     <chart [data]="curve"> 
     </div> 
    </div> 
    `, 
    directives: [Chart], 
}) 
export default class App { 
    data: number[][][]; 
} 

Quando cambio data, angolare sostituisce gli elementi <chart>, anche se la nuova matrice ha le stesse dimensioni. Mi piacerebbe solo aggiornare le proprietà dei grafici ma mantenere gli elementi (in modo da poter animare le modifiche dei dati).

È comprensibile che Angular sostituisca gli elementi poiché il nuovo array è un nuovo riferimento a un oggetto. Ma come posso aggirare questo?

+0

Potrebbe usare [ngForTrackBy] (https://angular.io/docs/ts/latest/guide/template-syntax.html#!#ngfortrackby)? – Michael

+0

@Michael Questo è esattamente quello che stavo cercando: 'trackByIndex (index: number, data: any) {return index; } '. Potresti fare una risposta, per favore? – danijar

+1

+1 Questa domanda ha una preoccupante visualizzazione delle quantità di visualizzazioni e di upvotes. ReactJS, ad esempio, genera un sibilo se si dimentica di fornire agli elementi della lista una proprietà 'chiave' in modo che l'elenco possa essere riscritto economicamente. –

risposta

5

Utilizzare ngForTrackBy dovrebbe aiutarti qui.

La seguente funzione dovrebbe aggiornare le proprietà dell'elemento mantenendo gli elementi nel DOM.

trackByIndex(index: number, data: any) { return index; } 
2

Working Plunker

piatto struttura dati

È possibile separare i metadati dei tuoi grafici (titolo, id, ecc) dai punti di dati reali che cambieranno e animato.

Il ciclo *ngFor utilizza l'array di metadati e ciascun componente del grafico dispone di un valore @Input() che preleva da un oggetto separato di punti dati.

// Metadata 
this.charts = [ 
    { 
    id: 1, 
    title: 'Chart Title 1', 
    }, 
    { 
    id: 2, 
    title: 'Chart Title 2', 
    } 
]; 

// Data Points 
this.chartData = { 
    1: [87, 95, 121, 20, 60, 131, 10, 139, 128, 99], 
    2: [56, 107, 107, 144, 43, 7, 67, 35, 141, 62] 
} 

Template

<div *ngFor="let chart of charts"> 
    <app-chart [inputMeta]="chart" [inputData]="chartData[chart.id]"></app-chart> 
</div> 

Poi nel componente grafico è possibile usare il ngOnChanges()lifecycle hook per aggiornare il grafico quando si aggiornano i punti di dati.

Problemi correlati