Como iterar sobre as chaves e valores com ng-repeat no AngularJS?


679

No meu controlador, tenho dados como: $scope.object = data

Agora, esses dados são o dicionário com chaves e valores de json.

Eu posso acessar o atributo com object.nameno modelo. Existe alguma maneira que eu possa iterar sobre as teclas também e exibi-las na tabela como

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

Os dados são assim

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

Respostas:


1407

E se:

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

Este método está listado nos documentos: https://docs.angularjs.org/api/ng/directive/ngRepeat


1
Deve funcionar: plnkr.co/edit/7AQF6k7hf2aZbWFmhVoX?p=preview . Você pode modificar isso até que pare de funcionar?
Josh David Miller

2
Ele funciona como um encanto. O único problema é que ele será alfabetizado pelas teclas para que a nomeação seja importante se a ordem do item for relevante para a exibição.
nome de exibição

29
@IsabelHM Por muitas razões, muitos de nós recomendamos não fazer iterações sobre objetos em um arquivo ngRepeat. De fato, uma vez ouvi um membro da equipe principal se arrepender de ter implementado a capacidade de fazê-lo! Geralmente é melhor transformar o objeto no controlador em uma matriz; isso torna a intenção mais clara e diminui o risco de comportamento estranho / imprevisível em certos casos. E você pode classificar da maneira usual. :-)
Josh David Miller

2
Como IsabelHM disse, a saída é ordenada alfabeticamente pelo nome. Existe uma maneira de forçá-lo a não fazê-lo?
newman

4
@sethflowers Como mencionei em um comentário anterior, não recomendo a iteração sobre as chaves nos objetos. Seria melhor convertê-lo em uma matriz no seu controlador. Assumindo que não há maneira idiomática de fazer isso com base no seu modelo de negócio, ES6 torna muito fácil: Object.getOwnPropertyNames(data).map(k => ({key:k, value:data[k]));.
Josh David Miller

132

Se você deseja editar o valor da propriedade com ligação bidirecional:

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

2
Obrigado! Por curiosidade, você encontrou essa técnica nos documentos em algum lugar? Eu procurei em vão até encontrar sua resposta aqui.
Roger

@cbk: Isto é o que eu estava procurando .. Obrigado
JKA

Muito obrigado, você salvou meu dia :)
Sergey

4
@ CBK não é o mesmo que usar ng-model="value"?
Mike Harrison

1
O @MikeHarrison ng-repeatestá essencialmente interagindo sobre o objeto e retornando pares de valores-chave. Pense nisso como for(var value in arrayOfValues) { ... }. Se você redesignar a variável valuedentro de seu loop, não estará alterando o que está dentro arrayOfValues, apenas apontando novamente valuepara um novo objeto.
Jon Senchyna

12

Eu não acho que exista uma função interna em angular para fazer isso, mas você pode fazer isso criando uma propriedade de escopo separada contendo todos os nomes de cabeçalho, e você pode preencher essa propriedade automaticamente assim:

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

$scope.objectHeaders = [];

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

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

1
Sua resposta funciona bem se for necessário fazer um loop através dos dados dentro de um controlador angular (o OP solicitou um loop de visualização).
Antonio Max

5

podemos seguir o procedimento abaixo para evitar a exibição de valores-chave em ordem alfabética.

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 na palavra-chave não permitida
amanuel2 17/06

4

Um exemplo de lista de tarefas que faz um loop sobre o objeto 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
O comentário sobre não usar colchetes foi realmente útil. Essa mudança corrigiu meu código. Obrigado.
Michael Khalili

Eu também. Alguém pode explicar por que o uso de colchetes corrigiu meu código?
beingalex

1

Exemplo completo aqui: -

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

Você pode fazê-lo no seu javascript (controlador) ou no seu 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>

Eu acredito que a maneira html é mais angular, mas você também pode fazer no seu controlador e recuperá-lo no seu html ...

também não é uma má idéia olhar para as chaves de objeto, elas fornecem uma matriz de chaves, se você precisar delas, mais informações aqui:

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


-2

Aqui está um exemplo de trabalho:

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

editado

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.