Abbiamo visto come la direttiva ng-repeat
consenta di creare elenchi in maniera molto semplice. Oltre a generare liste e tabelle, uno dei possibili utilizzi che possiamo fare di essa consiste nella generazione di voci di una select:
$scope.elencoCitta = ["Roma", "Milano", "Napoli", "Palermo"];
<select ng-model="selectedItem">
<option ng-repeat="citta in elencoCitta" value="{{citta}}">{{citta}}</option>
</select>
L'esempio presenta un elemento select
le cui voci vengono generate in base all'array di stringhe elencoCitta
. Trattandosi di semplici stringhe, abbiamo fatto coincidere il testo visualizzato in ciascuna voce con il valore ad essa associato. Grazie al data binding ci troveremo automaticamente nella variabile selectedItem
la stringa corrispondente alla voce selezionata dall'utente.
Spesso però ci troviamo a dover visualizzare un testo ed associare ad esso un codice. In questo caso possiamo utilizzare un array di oggetti come mostrato di seguito:
$scope.elencoCitta = [
{codice: "RM", nome: "Roma"},
{codice: "MI", nome: "Milano"},
{codice: "NA", nome: "Napoli"},
{codice: "PA", nome:"Palermo"}
];
<select ng-model="selectedItem">
<option ng-repeat="citta in elencoCitta" value="{{citta.codice}}">{{citta.nome}}</option>
</select>
Hai selezionato {{selectedItem}}!
Quando l'utente seleziona una voce, la variabile selectedItem avrà il valore del codice associato alla città. Questa soluzione può essere soddisfacente se quello che ci interessa è soltanto una proprietà dell'oggetto associato alla voce dell'elemento select
: nel caso specifico il codice. Ma se invece siamo interessati all'oggetto selezionato? Saremmo costretti a scandire l'array alla ricerca dell'oggetto corrispondente al codice selezionato.
In una situazione del genere è molto più comodo utilizzare la direttiva ng-options.
Riscriviamo pertanto il codice HTML nel seguente modo:
<select ng-model="selectedItem"
ng-options="citta.nome for citta in elencoCitta">
</select>
L'espressione assegnata alla direttiva indica di associare a ciascuna voce dell'elemento select
un oggetto citta
dell'array elencoCitta
visualizzando di ciascuno la proprietà nome
. In questo caso la selezione di un elemento da parte dell'utente fa sì che alla variabile selectedItem
venga associato direttamente l'oggetto selezionato.
È opportuno notare che il primo elemento delle voci di un select
è un elemento vuoto:
Questo accade perché inizialmente alla variabile selectedItem
non è assegnato alcun valore. Dal momento quindi che il valore di selectedItem
non corrisponde a nessuna voce dell'elenco, Angular ne aggiunge una nuova con valore vuoto e la imposta come voce selezionata.
Se non vogliamo questo comportamento, dobbiamo inizializzare la variabile selectedItem
assegnandole ad esempio il primo elemento dell'elenco:
$scope.selectedItem = $scope.elencoCitta[0];
La direttiva ng-options
prevede delle varianti all'espressione di base per la generazione delle opzioni che abbiamo visto nell'esempio precedente. Possiamo ad esempio specificare che, al posto dell'oggetto, vogliamo che al modello sia associato il valore di una proprietà:
<select ng-model="selectedItem"
ng-options="citta.codice as citta.nome for citta in elencoCitta">
</select>
Con questa espressione indichiamo che il valore da visualizzare è la proprietà nome
dell'oggetto citta, mentre il valore da assegnare al modello è la proprietà codice
.
Un'altra interessante variante consente di raggruppare le voci della select. Per fare un esempio, supponiamo di avere il seguente array:
$scope.elencoCitta = [
{codice: "RM", nome: "Roma", regione: "Lazio"},
{codice: "LT", nome: "Latina", regione: "Lazio"},
{codice: "MI", nome: "Milano" regione: "Lombardia"},
{codice: "NA", nome: "Napoli" regione: "Campania"},
{codice: "CO", nome: "Como" regione: "Lombardia"},
{codice: "PA", nome:"Palermo", regione: "Sicilia"},
{codice: "CA", nome: "Caserta" regione: "Campania"},
{codice: "AV", nome: "Avellino" regione: "Campania"},
{codice: "TP", nome:"Trapani", regione: "Sicilia"},
{codice: "AG", nome:"Agrigento", regione: "Sicilia"}
];
L'array contiene un elenco di oggetti che rappresentano alcune città italiane con le rispettive regioni di appartenenza. Possiamo visualizzare le città in una select
raggruppando le voci per regione come mostrato di seguito:
<select ng-model="selectedItem"
ng-options="citta.nome group by citta.regione for citta in elencoCitta">
</select>
Il risultato che otterremo è il seguente:
Come per ng-repeat
, anche con ng-options
abbiamo la possibilità di iterare sulle proprietà di un oggetto. Pertanto, se abbiamo il seguente oggetto:
$scope.citta = {codice: "RM", nome: "Roma", regione: "Lazio"};
Possiamo visualizzare l'elenco dei valori delle sue proprietà nel seguente modo:
<select ng-model="selectedItem"
ng-options="value for (key, value) in citta">
</select>
Il risultato ottenuto sarà analogo a quello di seguito illustrato: