Tabla de Contenidos
4.4 ng-repeat
Esta directiva es una de las más útiles de AngularJS y permite repetir una serie de tag HTML en función de un array 1) de datos de $scope. Su utilidad es para hacer tablas o similar, es decir para estructuras que se repiten.
Veamos un ejemplo para explicar su funcionamiento.
var app = angular.module("app", []);
app.controller("PruebaController", function($scope) {
$scope.provincias=[
{
idProvincia:2,
nombre:"Castellón"
},
{
idProvincia:3,
nombre:"Alicante"
},
{
idProvincia:1,
nombre:"Valencia"
},
{
idProvincia:7,
nombre:"Teruel"
},
{
idProvincia:5,
nombre:"Tarragona"
},
];
});
- Linea 4: La propiedad
provinciasdel$scopees un array de objetos.
<table>
<thead>
<tr>
<th>IdProvincia</th>
<th>Nombre</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="provincia in provincias">
<td>{{provincia.idProvincia}}</td>
<td>{{provincia.nombre}}</td>
</tr>
</tbody>
</table>
- Linea 9: La directiva
ng-repeathará que se repita el tag en el que se encuentra junto a su contenido. En nuestro caso es el tag<tr>y los dos tag<td>. Se repetirá tantas veces como elementos haya en el array. En nuestro caso el array esprovincias. Además se ha creado una nueva variable llamadaprovinciaque contiene cada uno de los elementos de array. - Línea 10: Para acceder a cada uno de los elementos del array y mostrar sus datos usamos la nueva variable
provinciaya que si no lo hacemos seguiremos accediendo a las propiedades del$scope. Es este caso accedemos a cada una de las propiedades deidProvinciamedianteprovincia.idProvincia. - Línea 11: Lo mismo que en el caso anterior pero ahora mostrando el nombre mediante
provincia.nombre.
Otras variables
Hemos visto que dentro del bucle de ng-repeat se crea una nueva variable definida por nosotros llamada provincia. AngularJS también crea otra serie se variables que podemos usar:
$index: Un número que indica el nº de elementos(de 0 a n-1).$first: Valetruesi estamos en el primer elemento del bucle.$last: Valetruesi estamos en el último elemento del bucle.$middle: Valetruesi no estamos ni en el primer ni en el último elemento del bucle.$even: Vale true si estamos en un elemento con$indexpar. (El 0 es par).$odd: Vale true si estamos en un elemento con$indeximpar. (El 0 es par).
Todas estas variable son muy útiles para cambiar el estilo de la filas.
Podemos modificar el ejemplo anterior de forma que las filas pares sean de fondo blanco y la impares de fondo amarillo:
<tr ng-repeat="provincia in provincias" style="background-color:{{$even?'white':'yellow'}}">
Se ha usado el operador ternario de javaScript para que cuando la variable $even sea true se retorne “white” y cuando sea false se retorne yellow.
Tambien podemos modificar el ejemplo haciendo que se muestre el Nº de fila en la que estamos:
<table>
<thead>
<tr>
<th>IdProvincia</th>
<th>Nombre</th>
<th>Nº fila</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="provincia in provincias" style="background-color:{{$even?'white':'yellow'}}">
<td>{{provincia.idProvincia}}</td>
<td>{{provincia.nombre}}</td>
<td>{{$index}}</td>
</tr>
</tbody>
</table>
Aquí hemos añadido una tercera columna para mostrar la variable $index.
Repetir varias etiquetas
ng-repeat sólo permite repetir un único tag HTML y su contenido, pero ¿cómo podemos repetir varios tags? Antes había que meterlo todo dentro de un tag <div> y repetir el tag <div> pero ahora se permite la siguiente estructura:
<strong ng-repeat-start="provincia in provincias" >{{provincia.idProvincia}}</strong> {{provincia.nombre}}
<br ng-repeat-end>{{provincia.nombre}}</br>
Así se repetirían el tag <strong> , el texto y el tag <br> tantas veces como elementos hay en el array.
Para delimitar el tag de inicio de la repetición se usa la directiva ng-repeat-start que funciona exactamente igual que ng-repeat y para delimitar el tag de fin de la repetición se usa la directiva ng-repeat-end
Claves primarias
Por defecto, si cambiamos el array de datos ,AngularJS automáticamente borrará todos los tag y los volverá a crear con todos los datos. Si hay muchos datos éso suele ser poco eficiente. Para paliarlo, AngularJS permite que le digamos qué columna es una clave única de nuestros objeto y así él puede optimizar el proceso.
La forma de hacerlo es añadir el texto track by y la propiedad que actúa como clave primaria.
La directiva entonces quedaría así:
<tr ng-repeat="provincia in provincias track by provincia.idProvincia">
Tras el texto track by se pone el nombre de la variable y luego la columna que es clave única.
Ejemplo
