In questo post andremo oltre la direttiva ngFor
core, in particolare andremo oltre quanto segue:
- cosa fa
ngFor
e qual è la sua sintassi - Quali sono gli errori più comuni associati a
ngFor
- Visibilità delle variabili
- Trovare la posizione dell’indice di un elemento
- Come strippare una tabella usando
even
eodd
- Identificare il
first
e l’elementolast
di una lista - Come fa
ngFor
a tenere traccia degli elementi, perché può essere importante per le prestazioni? - Come usare
trackBy
? - Quando usare
trackBy
? - Impara perché
ngFor
non è solo per gli array - Una domanda veloce per te alla fine sull’apprendimento
Quindi iniziamo ad immergerci in ngFor
! Qui sotto potete trovare anche una versione video di questo post se preferite, e il codice di questo post è disponibile qui.
Le caratteristiche di ngFor sono coperte anche in questo video, date un’occhiata:
Cosa possiamo fare con ngFor?
La direttiva di base ngFor
ci permette di costruire liste e tabelle di presentazione dei dati nei nostri template HTML. Prendiamo per esempio i seguenti dati:
Con ngFor
possiamo stampare questi dati sullo schermo sotto forma di tabella di dati, generando un HTML simile a questo:
Qual è la sintassi di ngFor?
Per usare ngFor
, creiamo un componente in modo da avere un template HTML funzionante:
Questo template genererà la tabella HTML che abbiamo mostrato poco sopra. Possiamo vedere in questo esempio la sintassi (più comune) per usare ngFor
:
- stiamo passando a
ngFor
un’espressione di iterazione - una variabile di loop chiamata
hero
è definita usando la parola chiavelet
, che è coerente con la sintassi Javascript - l’espressione è sotto la forma di
var i of items
, che è coerente con la funzionalità di iterazione di Javascriptof
Visibilità della variabile
Nota che la variabile del ciclo hero
è visibile solo all’interno del ciclo, non saresti in grado di accedervi fuori dalla sezione ngFor
.
Errori comuni di ngFor a cui fare attenzione
Se avete un background di AngularJs, vedrete questo errore alcune volte prima di abituarvi alla nuova sintassi di Angular:
Can't bind to 'ngFor' since it isn't a known property of 'tr'
Questo perché avete accidentalmente usato item in items
invece di item of items
, o avete dimenticato di aggiungere la parola chiave let
all’inizio dell’espressione:
Trovare l’indice di un elemento della lista
Un requisito molto comune è quello di aggiungere ad una lista la posizione dell’indice numerico del suo elemento. Possiamo ottenere l’indice dell’elemento corrente usando la variabile index
:
Nota che hai bisogno della parola chiave let per ottenere il valore dell’indice, altrimenti avrai un errore simile a questo:
Parser Error: Unexpected token = at column ...
Con questa modifica, l’HTML generato ora assomiglia al seguente:
Come strippare una tabella usando pari e dispari
Un’altra funzionalità molto comune necessaria quando si costruiscono le tabelle è quella di poter strippare una tabella aggiungendo una classe css diversa alle righe pari o dispari.
Diciamo che alla tabella di cui sopra vogliamo aggiungere una classe CSS even
se la riga è pari e la classe CSS odd
se la riga è dispari.
Per fare questo, abbiamo un paio di variabili disponibili per questo: even
e odd
, che possono essere usate nel seguente modo insieme a ngClass
:
Diamo un’occhiata all’HTML generato da questo template:
Come possiamo vedere, ngClass
ha aggiunto le classi CSS nelle righe giuste, come ci aspetteremmo.
Identificare il primo e l’ultimo elemento di una lista
Proprio come la funzionalità pari e dispari, ci sono anche altre due variabili che possono essere usate per identificare il primo e l’ultimo elemento della lista:
Questo aggiungerà una classe CSS chiamata first
al primo elemento della lista, e una classe CSS chiamata last
all’ultimo elemento della lista:
Come funziona ngFor quando aggiungiamo o eliminiamo elementi dalla lista?
Quando la lista di input viene modificata, ngFor
cercherà di evitare di creare e distruggere costantemente gli elementi DOM della lista, poiché questa è un’operazione costosa. Inoltre, quando passiamo a ngFor
una nuova lista, questo non significa che l’intera lista sarà ricostruita, cioè tutto il DOM ricreato.
Molti degli elementi DOM esistenti saranno riutilizzati e solo alcuni valori al loro interno saranno sovrascritti, e la decisione viene presa per ogni elemento della lista separatamente.
Per prendere questa decisione Angular ha bisogno di identificare ogni elemento della lista in modo unico, perché per esempio se passiamo una nuova lista con un ordine diverso, Angular cercherà di identificare gli elementi e riordinare gli elementi DOM della lista senza cancellarli e ricrearli.
Come vengono tracciati gli elementi della lista per default?
ngFor
per default traccia gli elementi della lista usando l’identità degli oggetti. Questo significa che se si costruisce una lista di nuovi oggetti da zero con gli stessi identici valori della lista precedente e si passa questa nuova lista a ngFor
, Angular non sarà in grado di dire che un dato elemento della lista è già presente o meno.
Dal punto di vista dell’identità degli oggetti, la nuova lista contiene un intero nuovo set di elementi, completamente diverso dal set precedente. Questo è il caso se per esempio interroghiamo di nuovo i dati dal backend.
Il tracciamento in base all’identità dell’oggetto è una buona strategia predefinita perché Angular non ha informazioni sull’oggetto e quindi non può dire quale proprietà dovrebbe usare per il tracciamento.
Perché questo può essere importante per le prestazioni?
Come vediamo, ngFor
fa già un sacco di ottimizzazioni out-of-the-box per cercare di riutilizzare il più possibile gli elementi DOM esistenti, ma lo fa in base all’identità dell’oggetto.
Nel caso di template con grandi liste, o liste che occupano una grande parte dello schermo, potremmo anche con queste ottimizzazioni incorrere in problemi di prestazioni e notare che l’UI è lenta a causa della grande quantità di elementi DOM che vengono creati e distrutti.
Se questo è il caso, possiamo configurare ngFor
per fare il tracking in base a qualcosa di diverso dall’identità dell’oggetto.
Come usare trackBy?
Possiamo fornire il nostro meccanismo di tracking degli elementi in una lista usando trackBy
. Dobbiamo passare una funzione a trackBy
, e la funzione prende un paio di argomenti, che sono un indice e l’elemento corrente:
Questa implementazione farebbe il tracking basato sulla proprietà id
.
Quando usare trackBy?
L’uso di trackBy
è un’ottimizzazione delle prestazioni e di solito non è necessario per default, in linea di principio è necessario solo se si incontrano problemi di prestazioni.
Diciamo che state spedendo a vecchi browser mobili o a vecchie versioni di IE: potreste considerare di applicare trackBy
come precauzione nelle vostre tabelle più grandi, ma dipende davvero dal vostro sistema e dal caso d’uso.
E’ ngFor solo per gli array?
In questo esempio, abbiamo passato a ngFor
un array di oggetti Javascript, ma in realtà non abbiamo necessariamente bisogno di passare un array a ngFor
per farlo funzionare.
Possiamo passargli qualsiasi tipo di Iterable Javascript in generale, inclusi gli Iterable creati dal framework stesso. Per illustrare questo, definiremo una direttiva per un elemento di configurazione chiamato hero
:
Ora possiamo usare questo elemento di configurazione nel nostro template nel modo seguente:
Ora interroghiamo questi dati dagli elementi di configurazione usando @ContentChildren
:
Vedi cosa è successo qui? Si scopre che il QueryList
è una classe che fa parte di Angular ed è essa stessa un Iterable! Quindi, anche se possiamo usarlo programmaticamente nella classe del componente, possiamo anche passarlo direttamente a ngFor
e iterare su di esso direttamente.
E lo stesso potrebbe essere fatto con qualsiasi altro Iterable nel nostro programma.
Spero che il post vi sia piaciuto, vi invito a dare un’occhiata alla lista qui sotto per altri post e risorse simili su Angular.
E se volete conoscere le caratteristiche più avanzate di Angular Core come ngFor, vi consigliamo di controllare il corso Angular Core Deep Dive, dove copriamo tutte le direttive di Angular Core in grande dettaglio.
Ti invito ad iscriverti alla nostra newsletter per essere avvisato quando usciranno altri post come questo:
Se hai appena iniziato ad imparare Angular, dai un’occhiata al corso Angular per principianti:
Altri post su Angular
Se ti è piaciuto questo post, dai un’occhiata anche ad altri post popolari che potresti trovare interessanti:
- Angular Router – Come costruire un menu di navigazione con Bootstrap 4 e percorsi annidati
- Angular Router – Visita guidata estesa, Evitare i trabocchetti comuni
- Componenti Angular – I fondamenti
- Come costruire app Angular usando Observable Data Services – Trabocchetti da evitare
- Introduzione ad Angular Forms – Template Driven vs Model Driven
- Angular ngFor – Imparare tutte le caratteristiche incluso trackBy, perché non è solo per gli array?
- Angular Universal in pratica – Come costruire app SEO Friendly a pagina singola con Angular
- Come funziona davvero il rilevamento dei cambiamenti in Angular?
- Typescript 2 Type Definitions Crash Course – Types e Npm, come sono collegati? @types, Compiler Opt-In Types: Quando usarli e perché?