如何在AngularJS中使用ng-repeat遍历键和值?


679

在我的控制器中,我有如下数据: $scope.object = data

现在,此数据是包含键和值的字典json

我可以object.name在模板中使用属性。有什么办法可以遍历键并将它们显示在表格中吗?

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

数据是这样的

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

Answers:


1407

怎么样:

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

该方法在docs中列出:https : //docs.angularjs.org/api/ng/directive/ngRepeat


1
它应该可以正常工作:plnkr.co/edit/7AQF6k7hf2aZbWFmhVoX?p=​​preview。在它停止工作之前,您可以对其进行修改吗?
乔什·大卫·米勒

2
它像一种魅力。唯一要注意的是,它将通过按键按字母顺序排列,因此如果项目顺序与显示相关,则命名很重要。
显示名称

29
@IsabelHM出于多种原因,我们很多人建议不要迭代中的对象ngRepeat。实际上,我曾经听过一个核心团队成员对实现这种能力感到遗憾!通常最好将控制器中的对象转换为数组。这样可以使意图更清晰,并减少某些情况下发生奇怪/不可预测行为的风险。您可以按照通常的方式进行排序。:-)
乔什·大卫·米勒

2
正如IsabelHM所说,输出按名称的字母顺序排列。有没有办法强迫它不这样做?
newman 2014年

4
@sethflowers正如我在前面的评论中提到的那样,我不建议迭代对象中的键。最好将其转换为控制器中的数组。假设有不地道的方式做到这一点根据你的商业模式,ES6使得它很容易:Object.getOwnPropertyNames(data).map(k => ({key:k, value:data[k]));
乔什·大卫·米勒

132

如果要通过两种方式编辑属性值:

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

2
谢谢!出于好奇,您是否在某个地方的文档中找到了此技术?我徒劳地寻找,直到在这里找到你的答案。
罗杰

@cbk:这就是我想要的。。谢谢
JKA

非常感谢您,您保存了我的一天:)
谢尔盖(Sergey)

4
@cbk和使用不一样ng-model="value"吗?
迈克·哈里森

1
@MikeHarrison ng-repeat本质上是遍历对象并返回键值对。觉得像for(var value in arrayOfValues) { ... }。如果您value在循环内重新分配变量,则不会更改内的内容arrayOfValues,而只是在指向value新对象。
乔恩·森奇纳

12

我不认为在angular中有内置函数可以执行此操作,但是您可以通过创建一个包含所有标头名称的单独的scope属性来做到这一点,并且可以像这样自动填充此属性:

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

$scope.objectHeaders = [];

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

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

1
如果需要循环访问角度控制器内的数据(OP要求进行视图循环),则您的答案会很好。
Antonio Max

5

我们可以按照以下过程来避免键值按字母顺序显示。

Java脚本

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

关键字中没有重复的单词-amanuel2 2016
6

4

一个待办事项列表示例,它通过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
关于不使用方括号的评论确实很有帮助。那个更改修复了我的代码。谢谢。
Michael Khalili

我也是。有人可以解释为什么使用大括号固定我的代码吗?
bealalex

1

完整示例如下:

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

您可以在javascript(控制器)或html(角度视图)中进行操作...

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>

我相信html的方式更加棱角分明,但您也可以在控制器中进行操作,并在html中进行检索...

查看对象键也不是一个坏主意,如果需要,它们会为您提供键数组,更多信息请参见:

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.