Wie iteriere ich mit ng-repeat in AngularJS über die Schlüssel und Werte?


679

In meinem Controller habe ich Daten wie: $scope.object = data

Diese Daten sind nun das Wörterbuch mit Schlüsseln und Werten von json.

Ich kann auf das Attribut mit object.namein der Vorlage zugreifen . Gibt es eine Möglichkeit, wie ich auch über die Schlüssel iterieren und sie in einer Tabelle wie anzeigen kann?

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

Die Daten sind so

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

Antworten:


1407

Wie wäre es mit:

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

Diese Methode ist in den Dokumenten aufgeführt: https://docs.angularjs.org/api/ng/directive/ngRepeat


1
Es sollte funktionieren: plnkr.co/edit/7AQF6k7hf2aZbWFmhVoX?p=preview . Können Sie das ändern, bis es nicht mehr funktioniert?
Josh David Miller

2
Es wirkt wie ein Zauber. Der einzige Haken ist, dass es durch die Tasten alphabetisch sortiert wird, sodass die Benennung wichtig ist, wenn die Artikelreihenfolge für die Anzeige relevant ist.
Anzeigename

29
@IsabelHM Aus vielen Gründen empfehlen viele von uns, nicht über Objekte in einem zu iterieren ngRepeat. Tatsächlich habe ich einmal gehört, dass ein Mitglied des Kernteams es bedauert, jemals die Möglichkeit dazu implementiert zu haben! Normalerweise ist es besser, das Objekt in der Steuerung in ein Array umzuwandeln. Dies macht die Absicht klarer und verringert in bestimmten Fällen das Risiko für seltsames / unvorhersehbares Verhalten. Und Sie können wie gewohnt sortieren. :-)
Josh David Miller

2
Wie IsabelHM sagte, ist die Ausgabe alphabetisch nach dem Namen geordnet. Gibt es eine Möglichkeit, dies zu erzwingen?
Newman

4
@sethflowers Wie bereits in einem früheren Kommentar erwähnt, empfehle ich nicht, Schlüssel in Objekten zu durchlaufen. Es ist besser, es in ein Array in Ihrem Controller zu konvertieren. Angenommen, es gibt keine idiomatische Möglichkeit, dies basierend auf Ihrem Geschäftsmodell zu tun, macht ES6 es sehr einfach : Object.getOwnPropertyNames(data).map(k => ({key:k, value:data[k]));.
Josh David Miller

132

Wenn Sie den Eigenschaftswert mit bidirektionaler Bindung bearbeiten möchten:

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

2
Vielen Dank! Haben Sie diese Technik aus Neugier irgendwo in Dokumenten gefunden? Ich habe vergeblich gesucht, bis ich hier Ihre Antwort gefunden habe.
Roger

@cbk: Dies ist, was ich gesucht habe .. Danke
JKA

Vielen Dank, Sie haben meinen Tag gerettet :)
Sergey

4
@cbk ist das nicht dasselbe wie mit ng-model="value"?
Mike Harrison

1
@MikeHarrison iteriert ng-repeatim Wesentlichen über das Objekt und gibt Schlüssel-Wert-Paare zurück. Stellen Sie es sich so vor for(var value in arrayOfValues) { ... }. Wenn Sie die Variable valuein Ihrer Schleife neu zuweisen , ändern Sie nicht, was sich darin befindet, sondern arrayOfValueszeigen nur valueauf ein neues Objekt.
Jon Senchyna

12

Ich glaube nicht, dass es dafür eine integrierte Funktion in Angular gibt, aber Sie können dies tun, indem Sie eine separate Bereichseigenschaft erstellen, die alle Headernamen enthält, und Sie können diese Eigenschaft automatisch wie folgt ausfüllen:

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

$scope.objectHeaders = [];

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

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

1
Ihre Antwort funktioniert einwandfrei, wenn Sie die Daten in einem Winkelregler durchlaufen müssen (OP fordert eine Ansichtsschleife an).
Antonio Max

5

Wir können das folgende Verfahren befolgen, um die Anzeige von Schlüsselwerten in alphabetischer Reihenfolge zu vermeiden.

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>

Duplizieren Sie in Schlüsselwort nicht erlaubt
amanuel2

4

Ein ToDo-Listenbeispiel, das das Objekt durchläuft 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
Der Kommentar, keine eckigen Klammern zu verwenden, war wirklich hilfreich. Diese Änderung hat meinen Code behoben. Vielen Dank.
Michael Khalili

Ich auch. Kann jemand erklären, warum die Verwendung von geschweiften Klammern meinen Code repariert hat?
Beingalex

1

Vollständiges Beispiel hier: -

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

Sie können dies in Ihrem Javascript (Controller) oder in Ihrem HTML (Winkelansicht) tun ...

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>

Ich glaube, der HTML-Weg ist eckiger, aber Sie können ihn auch in Ihrem Controller ausführen und in Ihrem HTML-Code abrufen ...

Auch keine schlechte Idee, sich die Objektschlüssel anzusehen, sie geben Ihnen ein Array der Schlüssel, wenn Sie sie brauchen, mehr Infos hier:

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


-2

Hier ist ein Arbeitsbeispiel:

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

bearbeitet

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.