Direttiva ng-repeat di AngularJS con esempio
โก Riepilogo intelligente
La direttiva ng-repeat in AngularJS visualizza una copia di un elemento per ogni elemento di una collezione definita nello scope del controller. Trasforma un array in una lista, una tabella o qualsiasi markup ripetuto senza dover scrivere un ciclo manuale.

Direttiva ng-repeat in AngularJS
Migliori ng-ripetere Direttive In AngularJS, `ng-repeat` viene utilizzato per visualizzare valori ripetuti definiti nel controller. A volte รจ necessario mostrare un elenco di elementi nella vista e `ng-repeat` visualizza un elenco definito nel controller nella pagina della vista.
โ ๏ธ Avviso di assistenza: AngularJS ha raggiunto Fine della vita il 31 dicembre 2021 e non riceve ulteriori patch o correzioni di sicurezza. La direttiva seguente rimane valida per la manutenzione delle applicazioni AngularJS 1.x esistenti; nelle versioni moderne Angular l'equivalente รจ il *ngFor Regolatore strutturale.
Esempio di direttiva ng-repeat di AngularJS
Vediamo un esempio della direttiva ng-repeat in AngularJS:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Event Registration</title> </head> <body> <h1>Guru99 Global Event</h1> <script src="https://code.angularjs.org/1.8.3/angular.js"></script> <div ng-app="DemoApp" ng-controller="DemoController"> <h1>Topics</h1> <ul> <li ng-repeat="tpname in TopicNames"> {{tpname.name}} </li> </ul> </div> <script> var app = angular.module('DemoApp', []); app.controller('DemoController', function($scope) { $scope.TopicNames = [ { name: "What controllers do from Angular's perspective" }, { name: "Controller Methods" }, { name: "Building a basic controller" } ]; }); </script> </body> </html>
Code Spiegazione:
- Nel controllore, definiamo innanzitutto l'array di elementi della lista da mostrare nella vista. Qui un array chiamato
TopicNamescontiene tre elementi, ciascuno dei quali รจ una coppia nome-valore. - L'array viene assegnato direttamente a
$scope.TopicNames, il che lo rende disponibile alla vista associata a questo controller. - I tag HTML
<ul>(elenco non ordinato) e<li>(elemento della lista) visualizza gli elementi. La direttiva ng-repeat itera su ogni voce nell'array etpnameรจ la variabile locale che contiene l'elemento corrente, quindi{{tpname.name}}stampa la sua proprietร nome.
โ ๏ธ Correzione: la spiegazione originale affermava che l'array veniva "aggiunto a una variabile membro chiamata topicsโ. Tale variabile non esiste nel codice: l'array viene assegnato direttamente a $scope.TopicNames, che รจ il nome a cui si riferisce la vista. L'introduzione di un secondo nome in questo punto รจ una causa comune di elenco vuoto.
Se il codice viene eseguito correttamente, nel browser viene visualizzato il seguente output.
Controller multipli AngularJS
In precedenza abbiamo visto un singolo controller in cui un metodo gestiva sia l'addizione che la sottrazionetraczione di numeri. In alternativa, รจ possibile utilizzare piรน controller per separare la logica in modo piรน pulito. Ad esempio, un controller puรฒ operare sui numeri mentre un altro opera sulle stringhe.
Vediamo un esempio di definizione di piรน controller in un'applicazione AngularJS.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Event Registration</title> </head> <body> <h1>Guru99 Global Event</h1> <script src="https://code.angularjs.org/1.8.3/angular.js"></script> <div ng-app="DemoApp"> <div ng-controller="firstcontroller"> <div ng-controller="secondcontroller"> {{lname}} </div> </div> </div> <script> var app = angular.module('DemoApp', []); app.controller('firstcontroller', function($scope) { $scope.pname = "firstcontroller"; }); app.controller('secondcontroller', function($scope) { $scope.lname = "secondcontroller"; }); </script> </body> </html>
Code Spiegazione:
- Sono definiti due controllori,
firstcontrollerandsecondcontroller. Ciascuno allega una variabile alla propria portata:pnamenel primo,lnamenel secondo. - Nella vista, il secondo controller รจ annidato all'interno del primo e l'espressione recita
lnamedall'ambito interno. Poichรฉ un controller nidificato eredita dal suo genitore,{{pname}}Anche in questo caso la questione si risolverebbe: l'ereditร scorre verso il basso, mai verso l'alto.
Se il codice viene eseguito correttamente, il testo secondo controller ร visualizzato.
Istruzioni per lโuso: track da con ng-repeat
L'errore piรน comune di ng-repeat รจ l'errore Duplicates in a repeater are not allowedSi verifica nel momento in cui una collezione contiene lo stesso valore due volte e blocca completamente il rendering dell'elenco.
La causa รจ l'identitร tracre. AngularJS necessita di una chiave stabile per ogni elemento in modo da poter riutilizzare i nodi DOM anzichรฉ ricostruirli ad ogni digest. Per impostazione predefinita, utilizza il valore dell'elemento stesso, quindi due valori identici entrano in conflitto.
<!-- Fails: the value 2 appears twice --> <li ng-repeat="n in [1, 2, 2, 3]">{{n}}</li> <!-- Works: position is unique even when values repeat --> <li ng-repeat="n in [1, 2, 2, 3] track by $index">{{n}}</li> <!-- migliori for records from a server: track by a real identifier --> <li ng-repeat="topic in TopicNames track by topic.id">{{topic.name}}</li>
La scelta tra le due forme รจ piรน importante di quanto possa sembrare a prima vista. Tracking by $index risolve sempre l'errore, perchรฉ una posizione รจ unica per definizione, ma lega ogni nodo DOM a uno slot piuttosto che a un record. Riordinando o filtrando la raccolta, quindi riutilizza i nodi sbagliati, che si manifestano come campi di input mantenutiping il testo della riga precedente.
Tracking mediante un identificatore autentico come topic.id evita completamente questo problema. AngularJS puรฒ seguire ogni record mentre si sposta, quindi riordina i nodi esistenti invece di distruggerli e ricostruirli. Su elenchi lunghi questo รจ anche notevolmente piรน veloce, poichรฉ un nuovo rendering interessa solo le righe che sono effettivamente cambiate. $index solo per array di valori semplici che non vengono mai riordinati.
Proprietร speciali disponibili all'interno di ng-repeat
Ogni iterazione di ng-repeat espone diverse proprietร di sola lettura nel proprio ambito figlio. Queste proprietร descrivono la posizione dell'elemento corrente all'interno della collezione, includendo numerazione, stili alternati e separatori, senza aggiungere alcuno stato extra al controller.
| Proprietร | Tipo | Valore |
|---|---|---|
$index |
Numero | Posizione dell'elemento corrente, a partire da 0 |
$first |
Booleano | Vero solo per il primo elemento |
$last |
Booleano | Vero solo per l'ultimo elemento |
$middle |
Booleano | Vero per ogni elemento che non รจ nรฉ il primo nรฉ l'ultimo |
$even |
Booleano | Vero quando $index รจ pari |
$odd |
Booleano | Vero quando $index รจ dispari |
Un utilizzo tipico li combina con ng-class per le strisce zebrateping, come in ng-class="{'row-alt': $odd}", oppure con ng-if per visualizzare un separatore su ogni riga tranne l'ultima, scritto ng-if="!$last". Visualizzare un numero di riga leggibile dall'uomo รจ semplice {{$index + 1}}, poichรฉ l'indice รจ basato su zero. Tutte e sei le proprietร vengono ricalcolate automaticamente ogni volta che la collezione cambia, quindi non รจ necessario ricalcolare nulla manualmente.
Errori comuni di ng-repeat e come risolverli
La maggior parte dei problemi con ng-repeat deriva da valori duplicati, dall'ereditarietร dello scope o dal fatto che la direttiva si trova sull'elemento sbagliato. Ciascun sintomo riportato di seguito ne indica la causa.
- Non sono ammessi duplicati in un ripetitore: la collezione contiene un valore ripetuto. Aggiungi
track by $index, o meglio,track byuna proprietร unica. - L'elenco non restituisce alcun risultato: il nome nella vista non corrisponde alla proprietร nell'ambito. Stampa la raccolta con
{{TopicNames}}per confermare che sia arrivato. - Ogni elemento si ripete, incluso il contenitore: ng-repeat รจ stato posizionato sul contenitore anzichรฉ sull'elemento. Spostalo su
<li>or<tr>. - La modifica di un campo di input modifica la riga sbagliata: L'elenco รจ tracked da
$indexmentre gli articoli vengono riordinati. Track invece tramite un identificatore stabile. - Le modifiche all'interno del ciclo non vengono mantenute: ogni iterazione ha il proprio ambito figlio, quindi la scrittura su un primitivo crea una copia locale. Scrivere su una proprietร dell'oggetto, come
item.done.




