Come usare ng-repeat per dizionari in AngularJs?


285

So che possiamo facilmente usare ng-repeat per oggetti json o array come:

<div ng-repeat="user in users"></div>

ma come possiamo usare ng-repeat per dizionari, ad esempio:

var users = null;
users["182982"] = "{...json-object...}";
users["198784"] = "{...json-object...}";
users["119827"] = "{...json-object...}";

Voglio usarlo con il dizionario degli utenti:

<div ng-repeat="user in users"></div>

È possibile?. Se sì, come posso farlo in AngularJs?

Esempio per la mia domanda: in C # definiamo dizionari come:

Dictionary<key,value> dict = new Dictionary<key,value>();

//and then we can search for values, without knowing the keys
foreach(var val in dict.Values)
{
}

Esiste una funzione integrata che restituisce i valori da un dizionario come in c #?


1
Qual è la differenza tra un dizionario e un oggetto JSON? Credo che non ce ne sia nessuno in JavaScript!
markmarijnissen,

8
@markmarijnissen: un oggetto JSON ha regole di sintassi più rigorose di un oggetto JavaScript . E, poiché siamo già in Pedant's Corner, non esiste un "Dizionario" in JavaScript. Li chiamiamo semplicemente oggetti.
Paul D. Waite,

Risposte:


556

Puoi usare

<li ng-repeat="(name, age) in items">{{name}}: {{age}}</li>

Vedi la documentazione di ngRepeat . Esempio: http://jsfiddle.net/WRtqV/1/


53
Non è quello che ho chiesto, ma esattamente quello che volevo. Grazie Artem Andreev
Vural

1
Come possiamo usare il filtro in questo ng-repeat. Non funziona nel mio caso quando sto usando un filtro di ricerca. Pronuncia <input type = "text" ng-model = "searchText" /> <li ng-repeat = "(nome, età) negli elementi | filtro: searchText"> {{name}}: {{age}} </ li> ...
Shekhar

1
@Shekhar Filter "filter" funziona solo con array. Puoi provare a creare una richiesta di funzionalità.
Artem Andreev,

2
Bello vedere un po 'di comunanza con Python :)
Robert King,

4
Puoi ottenere la funzione di filtro anche sui dizionari (oggetti) usando l'istruzione ng-if .. come ad esempio: <li ng-repeat = "(id, obj) negli elementi" ng-if = 'obj.sex = "female "'> {{obj.name}} {{obj.surname}} </li> ... dove gli elementi sono un insieme di persone indicizzate da una chiave.
giowild,

27

Vorrei anche menzionare una nuova funzionalità di AngularJSng-repeat , ovvero punti di inizio e fine ripetuti speciali . Quella funzionalità è stata aggiunta per ripetere una serie di elementi HTML anziché un solo elemento HTML genitore singolo .

Al fine di avviare l'uso del ripetitore e finale bisogna definirle utilizzando ng-repeat-starte ng-repeat-enddirettive, rispettivamente.

La ng-repeat-startdirettiva funziona in modo molto simile alla ng-repeatdirettiva. La differenza è che ripeterà tutti gli elementi HTML (incluso il tag su cui è definito) fino al tag HTML finale dove ng-repeat-endviene posizionato (incluso il tag con ng-repeat-end).

Codice di esempio (da un controller):

// ...
$scope.users = {};
$scope.users["182982"] = {name:"John", age: 30};
$scope.users["198784"] = {name:"Antonio", age: 32};
$scope.users["119827"] = {name:"Stephan", age: 18};
// ...

Modello HTML di esempio:

<div ng-repeat-start="(id, user) in users">
    ==== User details ====
</div>
<div>
    <span>{{$index+1}}. </span>
    <strong>{{id}} </strong>
    <span class="name">{{user.name}} </span>
    <span class="age">({{user.age}})</span>
</div>

<div ng-if="!$first">
   <img src="/some_image.jpg" alt="some img" title="some img" />
</div>
<div ng-repeat-end>
    ======================
</div>

L'output sarebbe simile al seguente (a seconda dello stile HTML):

==== User details ====
1.  119827 Stephan (18)
======================
==== User details ====
2.  182982 John (30)
[sample image goes here]
======================
==== User details ====
3.  198784 Antonio (32)
[sample image goes here]
======================

Come puoi vedere, ng-repeat-startripete tutti gli elementi HTML (incluso l'elemento con ng-repeat-start). Tutte ng-repeatle proprietà speciali (in questo caso $firste $index) funzionano anche come previsto.


Errore: [$ compile: uterdir] Attributo non terminato, trovato 'ng-repeat-start' ma nessuna corrispondenza 'ng-repeat-end' trovata.
zloctb,

@zloctb devi aver saltato il <div ng-repeat-end>..</div>tuo markup
John Kaster il

6

Gli sviluppatori JavaScript tendono a fare riferimento alla struttura di dati di cui sopra come oggetto o hash anziché come dizionario.

La tua sintassi sopra è errata mentre stai inizializzando l' usersoggetto come null. Presumo che questo sia un refuso, come dovrebbe leggere il codice:

// Initialize users as a new hash.
var users = {};
users["182982"] = "...";

Per recuperare tutti i valori da un hash, devi iterare su di esso usando un ciclo for:

function getValues (hash) {
    var values = [];
    for (var key in hash) {

        // Ensure that the `key` is actually a member of the hash and not
        // a member of the `prototype`.
        // see: http://javascript.crockford.com/code.html#for%20statement
        if (hash.hasOwnProperty(key)) {
            values.push(key);
        }
    }
    return values;
};

Se hai intenzione di lavorare molto con le strutture di dati in JavaScript, allora la libreria underscore.js merita sicuramente una visita. Underscore viene fornito con un valuesmetodo che eseguirà l'attività precedente per te:

var values = _.values(users);

Non uso Angular me stesso, ma sono abbastanza sicuro che ci sarà un metodo di convenienza integrato per iterare sui valori di un hash (ah, eccoci, Artem Andreev fornisce la risposta sopra :))


1
+1 per underscore.js e queste informazioni utili. Grazie Johnny!
Vural

0

In Angular 7, il seguente esempio semplice funzionerebbe (supponendo che il dizionario sia in una variabile chiamata d):

my.component.ts:

keys: string[] = [];  // declaration of class member 'keys'
// component code ...

this.keys = Object.keys(d);

my.component.html: (visualizzerà l'elenco di chiavi: coppie di valori)

<ul *ngFor="let key of keys">
    {{key}}: {{d[key]}}
</ul>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.