如何在AngularJS中使用ng-repeat迭代字典?

288

我知道我们可以很容易地使用ng-repeat来处理JSON对象或数组,比如:

<div ng-repeat="user in users"></div>

但是我们如何使用ng-repeat来处理字典呢,例如:

var users = null;
users["182982"] = "{...json-object...}";
users["198784"] = "{...json-object...}";
users["119827"] = "{...json-object...}";

我想将其与用户词典一起使用:

<div ng-repeat="user in users"></div>

这是否可能?如果是,AngularJS应该如何实现?

我的问题示例: 在C#中,我们会像这样定义字典:

Dictionary<key,value> dict = new Dictionary<key,value>();

//and then we can search for values, without knowing the keys
foreach(var val in dict.Values)
{
}

是否有内置函数可以像在C#中一样返回字典的值?


1
字典和JSON对象有什么区别?我认为在JavaScript中没有任何区别! - markmarijnissen
8
“JSON对象的语法规则比JavaScript对象更为严格。”(http://json.org/)。另外,既然我们已经在讲究细节的角落里了,JavaScript中并没有“字典”这个概念。我们只称它们为对象。 - Paul D. Waite
4个回答

564

53
这不是我问的,但却正是我想要的。谢谢Artem Andreev。 - Vural
1
我们如何在ng-repeat中使用过滤器?当我使用搜索过滤器时,它在我的情况下无法正常工作。例如:<input type="text" ng-model="searchText" /><li ng-repeat="(name, age) in items | filter:searchText ">{{name}}: {{age}}</li>... - Shekhar
1
@Shekhar,“filter”仅适用于数组。您可以尝试创建功能请求。 - Artem Andreev
2
很高兴看到与Python有一些共同点 :) - Rusty Rob
4
您可以使用 ng-if 语句在字典(对象)上获得过滤功能,例如:<li ng-repeat= "(id, obj) in items" ng-if='obj.sex="female"'>{{obj.name}} {{obj.surname}}</li> ... 其中 items 是一组由某个键索引的人。 - giowild
显示剩余5条评论

27

我还想提一下 AngularJS ng-repeat 的一个新功能,也就是特殊的重复起点和终点。这个功能被添加是为了重复一系列HTML元素而不仅仅是单个父HTML元素。

要使用重复器起始点和终点,您必须分别使用ng-repeat-startng-repeat-end指令来定义它们。

ng-repeat-start指令的工作方式与ng-repeat指令非常相似。不同之处在于它将重复所有HTML元素(包括其所定义的标签)直到放置ng-repeat-end的结束HTML标记(包括带有ng-repeat-end的标记)。

示例代码(来自控制器):

// ...
$scope.users = {};
$scope.users["182982"] = {name:"John", age: 30};
$scope.users["198784"] = {name:"Antonio", age: 32};
$scope.users["119827"] = {name:"Stephan", age: 18};
// ...

示例 HTML 模板:

<div ng-repeat-start="(id, user) in users">
    ==== User details ====
</div>
<div>
    <span>{{$index+1}}. </span>
    <strong>{{id}} </strong>
    <span class="name">{{user.name}} </span>
    <span class="age">({{user.age}})</span>
</div>

<div ng-if="!$first">
   <img src="/some_image.jpg" alt="some img" title="some img" />
</div>
<div ng-repeat-end>
    ======================
</div>

输出的结果类似于以下内容(根据 HTML 样式可能有所不同):

==== User details ====
1.  119827 Stephan (18)
======================
==== User details ====
2.  182982 John (30)
[sample image goes here]
======================
==== User details ====
3.  198784 Antonio (32)
[sample image goes here]
======================

正如您所看到的,ng-repeat-start重复所有HTML元素(包括带有ng-repeat-start的元素)。所有ng-repeat特殊属性(在本例中,包括$first$index)也按预期工作。


错误:[$compile:uterdir] 未终止的属性,发现 'ng-repeat-start',但没有找到匹配的 'ng-repeat-end'。 - zloctb
@zloctb,你在标记中可能跳过了<div ng-repeat-end>..</div> - John Kaster

6

JavaScript开发人员通常将上述数据结构称为对象或哈希,而不是字典。

您上面的语法是错误的,因为您将users对象初始化为null。我认为这是一个笔误,因为代码应该是这样的:

// Initialize users as a new hash.
var users = {};
users["182982"] = "...";

要从散列中检索所有值,您需要使用 for 循环迭代它:

function getValues (hash) {
    var values = [];
    for (var key in hash) {

        // Ensure that the `key` is actually a member of the hash and not
        // a member of the `prototype`.
        // see: http://javascript.crockford.com/code.html#for%20statement
        if (hash.hasOwnProperty(key)) {
            values.push(key);
        }
    }
    return values;
};

如果您计划在JavaScript中大量使用数据结构,则 underscore.js 库绝对值得一看。 Underscore 带有一个 values 方法,可以为您执行上述任务:
var values = _.values(users);

我自己不使用Angular,但我很确定它会有一个方便的方法来迭代哈希值(啊,这里有Artem Andreev提供的答案:)


1
感谢Johnny,赞一个underscore.js和这些有用的信息。 - Vural

-1
在Angular 7中,以下简单的示例将起作用(假设字典存储在名为d的变量中):

my.component.ts:

keys: string[] = [];  // declaration of class member 'keys'
// component code ...

this.keys = Object.keys(d);

my.component.html:(将显示键值对列表)

<ul *ngFor="let key of keys">
    {{key}}: {{d[key]}}
</ul>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接