Comment parcourir les clés et les valeurs avec ng-repeat dans AngularJS?

679

Dans mon contrôleur, j'ai des données comme: $scope.object = data

Maintenant, ces données sont le dictionnaire avec les clés et les valeurs de json.

Je peux accéder à l'attribut avec object.namedans le modèle. Existe-t-il un moyen de parcourir les touches également et de les afficher dans un tableau comme

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

Les données sont comme ça

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

Réponses:

1407

Que diriez-vous:

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

Cette méthode est répertoriée dans les documents: https://docs.angularjs.org/api/ng/directive/ngRepeat

Josh David Miller
la source
1
Cela devrait fonctionner: plnkr.co/edit/7AQF6k7hf2aZbWFmhVoX?p=preview . Pouvez-vous modifier cela jusqu'à ce qu'il cesse de fonctionner?
Josh David Miller
2
Il fonctionne comme un charme. Le seul hic est qu'il sera alphabétisé par les touches, donc la dénomination est importante si l'ordre des articles est pertinent pour l'affichage.
nom d'affichage
29
@IsabelHM Pour de nombreuses raisons, beaucoup d'entre nous déconseillent d'itérer sur les objets dans un ngRepeat. En fait, j'ai entendu un jour un membre de l'équipe centrale regretter d'avoir mis en œuvre cette capacité! Il est généralement préférable de transformer l'objet du contrôleur en tableau; cela rend l'intention plus claire et diminue le risque de comportement étrange / imprévisible dans certains cas. Et vous pouvez trier de la manière habituelle. :-)
Josh David Miller
2
Comme IsabelHM l'a dit, la sortie est classée par ordre alphabétique par nom. Existe-t-il un moyen de le forcer à ne pas le faire?
newman
4
@sethflowers Comme je l'ai mentionné dans un commentaire précédent, je ne recommande pas d'itérer sur les clés des objets. Il serait préférable de le convertir en un tableau dans votre contrôleur. Si l'on suppose qu'il n'y a pas moyen idiomatiques de le faire en fonction de votre modèle d'affaires, ES6, il est très facile: Object.getOwnPropertyNames(data).map(k => ({key:k, value:data[k]));.
Josh David Miller
132

Si vous souhaitez modifier la valeur de la propriété avec une liaison bidirectionnelle:

<tr ng-repeat="(key, value) in data">
    <td>{{key}}<input type="text" ng-model="data[key]"></td>
</tr>
cbk
la source
2
Je vous remercie! Par curiosité, avez-vous trouvé cette technique dans les documents quelque part? J'ai cherché en vain jusqu'à trouver ici votre réponse.
Roger
@cbk: C'est ce que je cherchais .. Merci
JKA
Merci beaucoup, vous m'avez sauvé la journée :)
Sergey
4
@cbk n'est-ce pas la même chose que d'utiliser ng-model="value"?
Mike Harrison
1
@MikeHarrison itère ng-repeatessentiellement sur l'objet et renvoie des paires clé-valeur. Pensez-y comme for(var value in arrayOfValues) { ... }. Si vous réaffectez la variable à l' valueintérieur de votre boucle, vous ne changez pas ce qui est à l'intérieur arrayOfValues, vous redirigez simplement valuevers un nouvel objet.
Jon Senchyna
12

Je ne pense pas qu'il y ait une fonction intégrée en angulaire pour faire cela, mais vous pouvez le faire en créant une propriété d'étendue distincte contenant tous les noms d'en-tête, et vous pouvez remplir cette propriété automatiquement comme ceci:

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

$scope.objectHeaders = [];

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

// Output: [ 'foo', 'bar' ]
Felipe Castro
la source
1
Votre réponse fonctionne bien si vous avez besoin de parcourir les données à l'intérieur d'un contrôleur angulaire (OP a demandé une boucle de vue).
Antonio Max
5

nous pouvons suivre la procédure ci-dessous pour éviter l'affichage des valeurs-clés dans l'ordre alphabétique.

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>
user3414423
la source
Dupliquer dans le mot clé non autorisé
amanuel2
4

Un exemple de liste de tâches qui passe en boucle sur l'objet en 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>

Ashish Saxena
la source
1
Le commentaire de ne pas utiliser de crochets était très utile. Ce changement a corrigé mon code. Merci.
Michael Khalili
Moi aussi. Quelqu'un peut-il expliquer pourquoi l'utilisation de crochets a corrigé mon code?
beingalex
1

Exemple complet ici: -

<!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>
Ajay Kumar
la source
0

Vous pouvez le faire dans votre javascript (contrôleur) ou dans votre html (vue angulaire) ...

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>

Je crois que la façon html est plus angulaire, mais vous pouvez aussi le faire dans votre contrôleur et le récupérer dans votre html ...

aussi pas une mauvaise idée de regarder les clés d'objet, elles vous donnent le tableau des clés si vous en avez besoin, plus d'informations ici:

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

Alireza
la source
-2

Voici un exemple de travail:

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

édité

Nakul Wali
la source