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",
}

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


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>

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

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>

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>


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>


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


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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.