¿Cómo usar ng-repeat para diccionarios en AngularJs?


285

Sé que podemos usar fácilmente ng-repeat para objetos json o matrices como:

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

pero, ¿cómo podemos usar ng-repeat para diccionarios, por ejemplo:

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

Quiero usar eso con el diccionario de usuarios:

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

¿Es posible?. En caso afirmativo, ¿cómo puedo hacerlo en AngularJs?

Ejemplo para mi pregunta: en C # definimos diccionarios como:

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)
{
}

¿Hay una función incorporada que devuelve los valores de un diccionario como en c #?


1
¿Cuál es la diferencia entre un diccionario y un objeto JSON? ¡Creo que no hay ninguno en JavaScript!
markmarijnissen

8
@markmarijnissen: un objeto JSON tiene reglas de sintaxis más estrictas que un objeto JavaScript . Y, como ya estamos en el Rincón del Pedante, no existe un "Diccionario" en JavaScript. Simplemente los llamamos objetos.
Paul D. Waite

Respuestas:


556

Puedes usar

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

Consulte la documentación de ngRepeat . Ejemplo: http://jsfiddle.net/WRtqV/1/


53
Esto no es lo que pedí, sino exactamente lo que quería. Gracias Artem Andreev
Vural

1
¿Cómo podemos usar filter en esta ng-repeat? No funciona en mi caso cuando estoy usando un filtro de búsqueda. Diga <input type = "text" ng-model = "searchText" /> <li ng-repeat = "(nombre, edad) en elementos | filtro: searchText"> {{nombre}}: {{edad}} </ li> ...
Shekhar

1
@Shekhar Filter "filter" solo funciona con matrices. Puede intentar crear una solicitud de función.
Artem Andreev

2
Es bueno ver algo en común con Python :)
Robert King

44
Puede obtener la función de filtro incluso en los diccionarios (objetos) utilizando la instrucción ng-if ... como por ejemplo: <li ng-repeat = "(id, obj) en los elementos" ng-if = 'obj.sex = "female "'> {{obj.name}} {{obj.surname}} </li> ... donde items es un conjunto de personas indexadas por alguna clave.
giowild

27

También me gustaría mencionar una nueva funcionalidad de AngularJSng-repeat , a saber, puntos especiales de inicio y finalización de repetición . Esa funcionalidad se agregó para repetir una serie de elementos HTML en lugar de un solo elemento HTML principal.

Para utilizar los puntos de inicio y finalización del repetidor, debe definirlos utilizando las directivas ng-repeat-starty ng-repeat-endrespectivamente.

La ng-repeat-startdirectiva funciona de manera muy similar a la ng-repeatdirectiva. La diferencia es que repetirá todos los elementos HTML (incluida la etiqueta en la que se define) hasta la etiqueta HTML final donde ng-repeat-endse coloca (incluida la etiqueta con ng-repeat-end).

Código de muestra (de un controlador):

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

Plantilla HTML de muestra:

<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>

La salida sería similar a la siguiente (dependiendo del estilo 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]
======================

Como puede ver, ng-repeat-startrepite todos los elementos HTML (incluido el elemento con ng-repeat-start). Todas ng-repeatlas propiedades especiales (en este caso $firsty $index) también funcionan según lo esperado.


Error: [$ compile: uterdir] Atributo no terminado, encontrado 'ng-repeat-start' pero no encontrado 'ng-repeat-end'.
zloctb

@zloctb debe haber omitido <div ng-repeat-end>..</div>su marcado
John Kaster

6

Los desarrolladores de JavaScript tienden a referirse a la estructura de datos anterior como un objeto o hash en lugar de un Diccionario.

Su sintaxis anterior es incorrecta ya que está inicializando el usersobjeto como nulo. Supongo que esto es un error tipográfico, ya que el código debería leer:

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

Para recuperar todos los valores de un hash, debe iterar sobre él utilizando un bucle 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;
};

Si planea hacer mucho trabajo con estructuras de datos en JavaScript, entonces vale la pena echar un vistazo a la biblioteca underscore.js . El subrayado viene con un valuesmétodo que realizará la tarea anterior para usted:

var values = _.values(users);

No uso Angular yo mismo, pero estoy bastante seguro de que habrá un método de conveniencia incorporado para iterar sobre los valores de un hash (ah, ahí vamos, Artem Andreev proporciona la respuesta anterior :))


1
+1 para underscore.js y estas informaciones útiles. Gracias Johnny!
Vural

0

En Angular 7, el siguiente ejemplo simple funcionaría (suponiendo que el diccionario esté en una variable llamada d ):

my.component.ts:

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

this.keys = Object.keys(d);

my.component.html: (mostrará la lista de pares clave: valor)

<ul *ngFor="let key of keys">
    {{key}}: {{d[key]}}
</ul>
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.