¿Cómo iterar sobre las claves y los valores con ng-repeat en AngularJS?


679

En mi controlador, tengo datos como: $scope.object = data

Ahora estos datos son el diccionario con claves y valores de json.

Puedo acceder al atributo con object.nameen la plantilla. ¿Hay alguna manera de que pueda iterar sobre las teclas también y mostrarlas en la tabla como

<tr><td> {{key}} </td> <td> data.key </td>

Los datos son así

{
    "id": 2,
    "project": "wewe2012",
    "date": "2013-02-26",
    "description": "ewew",
    "eet_no": "ewew",
}

Respuestas:


1407

Qué tal si:

<table>
  <tr ng-repeat="(key, value) in data">
    <td> {{key}} </td> <td> {{ value }} </td>
  </tr>
</table>

Este método aparece en los documentos: https://docs.angularjs.org/api/ng/directive/ngRepeat


1
Debería funcionar: plnkr.co/edit/7AQF6k7hf2aZbWFmhVoX?p=preview . ¿Puedes modificar eso hasta que deje de funcionar?
Josh David Miller

2
Funciona a las mil maravillas. El único inconveniente es que se alfabetizará por las teclas, por lo que el nombre importa si el orden del artículo es relevante para la pantalla.
nombre para mostrar el

29
@IsabelHM Por muchas razones, muchos de nosotros recomendamos no iterar sobre objetos en un ngRepeat. De hecho, una vez escuché que un miembro del equipo central lamentaba haber implementado la capacidad de hacerlo. Por lo general, es mejor transformar el objeto en el controlador en una matriz; Esto aclara la intención y disminuye el riesgo de comportamiento extraño / impredecible en ciertos casos. Y puedes ordenar de la manera habitual. :-)
Josh David Miller

2
Como dijo IsabelHM, la salida se ordena alfabéticamente por el nombre. ¿Hay alguna manera de obligarlo a no hacerlo?
newman

44
@sethflowers Como mencioné en un comentario anterior, no recomiendo iterar sobre las claves de los objetos. Sería mejor convertirlo a una matriz en su controlador. Suponiendo que no hay manera de hacer esto idiomática basado en su modelo de negocio, ES6 hace que sea muy fácil: Object.getOwnPropertyNames(data).map(k => ({key:k, value:data[k]));.
Josh David Miller el

132

Si desea editar el valor de la propiedad con enlace bidireccional:

<tr ng-repeat="(key, value) in data">
    <td>{{key}}<input type="text" ng-model="data[key]"></td>
</tr>

2
¡Gracias! Por curiosidad, ¿encontraste esta técnica en documentos en algún lugar? Busqué en vano hasta encontrar tu respuesta aquí.
Roger

@cbk: Esto es lo que estaba buscando ... Gracias
JKA

Muchas gracias, me salvaste el día :)
Sergey

44
@cbk, ¿no es lo mismo que usar ng-model="value"?
Mike Harrison el

1
@MikeHarrison ng-repeatesencialmente está iterando sobre el objeto y devolviendo pares clave-valor. Piensa en ello como for(var value in arrayOfValues) { ... }. Si reasigna la variable valuedentro de su ciclo, no está cambiando lo que está dentro arrayOfValues, solo está volviendo a señalar valuea un nuevo objeto.
Jon Senchyna

12

No creo que haya una función incorporada en angular para hacer esto, pero puede hacerlo creando una propiedad de ámbito separada que contenga todos los nombres de encabezado, y puede completar esta propiedad automáticamente de esta manera:

var data = {
  foo: 'a',
  bar: 'b'
};

$scope.objectHeaders = [];

for ( property in data ) {
  $scope.objectHeaders.push(property); 
}

// Output: [ 'foo', 'bar' ]

1
Su respuesta funciona bien si uno necesita recorrer los datos dentro de un controlador angular (OP solicitó un bucle de vista).
Antonio Max

5

podemos seguir el siguiente procedimiento para evitar la visualización de valores-clave en orden alfabético.

Javascript

$scope.data = {
   "id": 2,
   "project": "wewe2012",
   "date": "2013-02-26",
   "description": "ewew",
   "eet_no": "ewew",
};
var array = [];
for(var key in $scope.data){
    var test = {};
    test[key]=$scope.data[key];
    array.push(test);
}
$scope.data = array;

HTML

<p ng-repeat="obj in data">
   <font ng-repeat="(key, value) in obj">
      {{key}} : {{value}}
   </font>
</p>

Duplicar en palabra clave no alocado
amanuel2

4

Un ejemplo de lista de tareas que recorre objetos por ng-repeat:

var app = angular.module('toDolistApp', []);
app.controller('toDoListCntrl', function() {
  var self = this;
  self.toDoListItems = {};// []; //dont use square brackets if keys are string rather than numbers.
  self.doListCounter = 0;

  self.addToDoList = function() {		  		   
    var newToDoItem = {};
    newToDoItem.title     = self.toDoEntry;
    newToDoItem.completed = false;		   

    var keyIs = "key_" + self.doListCounter++;  		   

    self.toDoListItems[keyIs] = newToDoItem;		   
    self.toDoEntry = ""; //after adding the item make the input box blank.
  };
});

app.filter('propsCounter', function() {
  return function(input) {
    return Object.keys(input).length;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="toDolistApp">    
  <div ng-controller="toDoListCntrl as toDoListCntrlAs">
    Total Items: {{toDoListCntrlAs.toDoListItems | propsCounter}}<br />
    Enter todo Item:  <input type="text" ng-model="toDoListCntrlAs.toDoEntry"/>
    <span>{{toDoListCntrlAs.toDoEntry}}</span>
    <button ng-click="toDoListCntrlAs.addToDoList()">Add Item</button> <br/>
    <div ng-repeat="(key, prop) in toDoListCntrlAs.toDoListItems"> 
      <span>{{$index+1}} : {{key}}   : Title = {{ prop.title}} : Status = {{ prop.completed}} </span>
    </div>     
  </div>    
</body>


1
El comentario sobre no usar corchetes fue realmente útil. Ese cambio arregló mi código. Gracias.
Michael Khalili

Yo también. ¿Alguien puede explicar por qué el uso de llaves se corrigió mi código?
beingalex

1

Ejemplo completo aquí: -

<!DOCTYPE html >
<html ng-app="dashboard">
<head>
<title>AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<link rel="stylesheet" href="./bootstrap.min.css">
<script src="./bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
</head>
<body ng-controller="myController">
    <table border='1'>
        <tr ng-repeat="(key,val) in collValues">
            <td ng-if="!hasChildren(val)">{{key}}</td>  
            <td ng-if="val === 'string'">
                <input type="text" name="{{key}}"></input>
            </td>
            <td ng-if="val === 'number'">
                <input type="number" name="{{key}}"></input>
            </td>
            <td ng-if="hasChildren(val)" td colspan='2'>
                <table border='1' ng-repeat="arrVal in val">
                    <tr ng-repeat="(key,val) in arrVal">
                        <td>{{key}}</td>    
                        <td ng-if="val === 'string'">
                            <input type="text" name="{{key}}"></input>
                        </td>
                        <td ng-if="val === 'number'">
                            <input type="number" name="{{key}}"></input>
                        </td>
                    </tr>
                </table>                
            </td>

        </tr>       
    </table>
</body>

<script type="text/javascript">

    var app = angular.module("dashboard",[]);
    app.controller("myController",function($scope){
        $scope.collValues = {
            'name':'string',
            'id':'string',
            'phone':'number',
            'depart':[
                    {
                        'depart':'string',
                        'name':'string' 
                    }
            ]   
        };

        $scope.hasChildren = function(bigL1) {
            return angular.isArray(bigL1);
} 
    });
</script>
</html>


0

Puede hacerlo en su javascript (controlador) o en su html (vista angular) ...

js:

$scope.arr = [];
for ( p in data ) {
  $scope.arr.push(p); 
}

html:

<tr ng-repeat="(k, v) in data">
    <td>{{k}}<input type="text" ng-model="data[k]"></td>
</tr>

Creo que la forma html es más angular, pero también puede hacerlo en su controlador y recuperarlo en su html ...

tampoco es una mala idea mirar las teclas de Objeto, te dan una serie de teclas si las necesitas, más información aquí:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys


-2

Aquí hay un ejemplo de trabajo:

<div class="item item-text-wrap" ng-repeat="(key,value) in form_list">
  <b>{{key}}</b> : {{value}}
</div>

editado

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.