Mientras preparaba mi clase para el curso de angular que para la capacitación de personal en la empresa donde trabajo. Me puse a revisar detenidamente la documentación de ngFor, algo tan banal y simple que nunca falta en un proyecto angular. Y me di cuenta que había un atributo que nunca había usado o percatado de su existencia, el “track by”.
Cuando actualizamos una propiedad en nuestro componente este dispara en property binding haciendo que la template se reescriba con la nueva lista, pero mucho ojo! No es que agregue nuevos elementos si no lo que pasa es que limpia todo los elementos en el dom y los vuelve a escribir, si bien en una lista pequeña esto no importa mucho, si la cantidad de elementos es grande o el objeto iterado tiene muchas propiedades puede traer problemas en performance de la aplicación.
Ahora necesitamos algo importante para que angular pueda trabajar correctamente nuestra lista, y es que cada elemento tenga un identificador único, de esa forma angular sabrá qué objetos son nuevos en a lista y cuales ya los tienes impresos.
mucho cuchicheo, vamos con el ejemplo!
Mi lista de compras
Bien digamos que tengo una aplicación simple que tiene mi lista de compras del super(de verdad tengo que hacer compras este finde).
Y tenemos un botón que lo que hace es cambiar la lista por una idéntica! pero con 2 elementos nuevos.
Veamos que hay en el código
app.component.ts
import { Component, VERSION } from '@angular/core';
import { Item } from './models/item.model';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
lista: Item[] = []
constructor() {
this.lista = [
{id: '1', desc: 'Ajos'},
{id: '2', desc: 'Tomates'},
{id: '3', desc: 'Papas'},
{id: '4', desc: 'Cebollas'},
];
}
actualizar() {
this.lista = [
{id: '1', desc: 'Ajos'},
{id: '2', desc: 'Tomates'},
{id: '3', desc: 'Papas'},
{id: '4', desc: 'Cebollas'},
{id: '5', desc: 'mostaza'},
{id: '6', desc: 'Mayonesa'},
];
}
}
app.component.html
<h1>Lista de compras</h1>
<button (click)="actualizar()"> Actualizar </button>
<ul>
<li *ngFor="let item of lista">{{ item.desc }}</li>
</ul>
Al presionar el botón vemos que se reescribe toda la lista
Como podemos con el tooldev de chrome vemos que todos los elemento está volviendo a reescribirse a pesar de que la lista solo agrega 2 elementos nuevos.
Ahora vamos a crear un método el cual indiquemos cual como pueden identificar como único los elementos de la lista.
trackByFn(index: number, item: Item) {
return item.id;
}
el primer parámetro es el índice del elemento y el segundo es el propio elemento, lo que debe retornar nuestra función es cual es la propiedad o identificador que hace único a ese elemento de la lista. En este caso nuestro caso la propiedad “id”.
Ahora le indicamos a nuestro ngFor que esta es la trackby
y magia!
Como vemos resaltado en morado, lo único que se escribió en el DOM fueron los 2 nuevos elementos, dándole un mejor rendimiento a nuestra aplicación.
Ahora manos a la obra y optimiza tus ngFor, no olvides apoyarme con unas palmaditas.
Puede seguirme en youtube tambien tengo unos cuantos tutoriales.
https://www.youtube.com/channel/UCVXDZUMTSPpM8tVCjiXnz7Q
Aquí tiene el código!
Top comments (2)
¿Sirve también para cuando usas observables con el pipe | async? me surgió esa duda.
Si, también funciona con el pipe Async, mira este ejemplo
stackblitz.com/edit/trackby-obs?fi...