Jak iterować po kluczach i wartościach z powtórzeniem ng w AngularJS?


679

W moim kontrolerze mam dane takie jak: $scope.object = data

Teraz tymi danymi jest słownik z kluczami i wartościami z json.

Mogę uzyskać dostęp do atrybutu za object.namepomocą szablonu. Czy jest jakiś sposób, że mogę również iterować klucze i wyświetlać je w tabeli jak

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

Dane są takie

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

Odpowiedzi:


1407

Co powiesz na:

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

Ta metoda jest wymieniona w dokumentacji: https://docs.angularjs.org/api/ng/directive/ngRepeat


1
Powinno działać: plnkr.co/edit/7AQF6k7hf2aZbWFmhVoX?p=preview . Czy możesz to zmienić, dopóki nie przestanie działać?
Josh David Miller

2
To działa jak urok. Jedynym haczykiem jest to, że będzie on alfabetycznie przypisany do klawiszy, więc nazywanie ma znaczenie, jeśli kolejność elementów jest zgodna z wyświetlaniem.
nazwa wyświetlana

29
@IsabelHM Z wielu powodów wielu z nas odradza iterację obiektów ngRepeat. W rzeczywistości kiedyś usłyszałem, jak członek podstawowego zespołu żałuje, że wdrożył taką możliwość! Zwykle lepiej jest przekształcić obiekt w kontrolerze w tablicę; to sprawia, że ​​intencja jest jaśniejsza i zmniejsza ryzyko dziwnych / nieprzewidywalnych zachowań w niektórych przypadkach. I możesz sortować w zwykły sposób. :-)
Josh David Miller,

2
Jak powiedział IsabelHM, dane wyjściowe są uporządkowane alfabetycznie według nazwy. Czy istnieje sposób, aby zmusić go do tego?
newman

4
@sethflowers Jak wspomniałem w poprzednim komentarzu, nie polecam iteracji po kluczach w obiektach. Lepiej byłoby przekonwertować go na tablicę w kontrolerze. Zakładając, że nie jest idiomatyczne sposób to zrobić na podstawie modelu biznesowego, ES6 sprawia, że bardzo łatwo: Object.getOwnPropertyNames(data).map(k => ({key:k, value:data[k]));.
Josh David Miller,

132

Jeśli chcesz edytować wartość właściwości z wiązaniem dwukierunkowym:

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

2
Dziękuję Ci! Czy z ciekawości znalazłeś tę technikę w dokumentacji? Na próżno szukałem, aż tutaj znajdę odpowiedź.
Roger

@cbk: Właśnie tego szukałem. Dzięki
JKA

Dziękuję bardzo, uratowałeś mi dzień :)
Sergey

4
@cbk to nie to samo, co używanie ng-model="value"?
Mike Harrison,

1
@MikeHarrison ng-repeatzasadniczo iteruje obiekt i zwraca pary klucz-wartość. Pomyśl o tym jak for(var value in arrayOfValues) { ... }. Jeśli ponownie przypiszesz zmienną valuedo pętli, nie zmienisz tego, co jest w środku arrayOfValues, po prostu ponownie wskażesz valuenowy obiekt.
Jon Senchyna,

12

Nie sądzę, że jest do tego wbudowana funkcja kątowa, ale możesz to zrobić, tworząc osobną właściwość zasięgu zawierającą wszystkie nazwy nagłówków, i możesz wypełnić tę właściwość automatycznie w następujący sposób:

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

$scope.objectHeaders = [];

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

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

1
Twoja odpowiedź działa dobrze, jeśli trzeba przejrzeć dane wewnątrz kontrolera kątowego (OP poprosił o pętlę widoku).
Antonio Max

5

możemy wykonać poniższą procedurę, aby uniknąć wyświetlania kluczowych wartości w kolejności alfabetycznej.

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>

Duplikat słowa kluczowego nie został udostępniony
amanuel2

4

Lista todo przykład, który pętle nad obiektem przez 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
Komentarz o nieużywaniu nawiasów kwadratowych był bardzo pomocny. Ta zmiana naprawiła mój kod. Dzięki.
Michael Khalili

Ja też. Czy ktoś może wyjaśnić, dlaczego użycie nawiasów klamrowych naprawiło mój kod?
beingalex

1

Kompletny przykład tutaj: -

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

Możesz to zrobić w swoim javascript (kontrolerze) lub HTML (widok kątowy) ...

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>

Wierzę, że sposób HTML jest bardziej kątowy, ale możesz również zrobić to w kontrolerze i pobrać go w swoim HTML ...

również niezły pomysł, aby spojrzeć na klucze Object, dają one tablicę kluczy, jeśli ich potrzebujesz, więcej informacji tutaj:

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


-2

Oto działający przykład:

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

edytowane

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.