AngularJS ng-repeat 指令及示例

⚡ 智能摘要

AngularJS 中的 ng-repeat 指令会为控制器作用域中定义的集合中的每个元素渲染一份副本。它无需编写手动循环即可将数组转换为列表、表格或任何重复标记。

  • 🔁 核心行为: ng-repeat 会为每个项目克隆一次其宿主元素,因此该指令应该放在被重复的元素上,而不是其容器上。
  • 🏷️ 循环变量: 单词“in”之前的名称将成为该克隆中当前项的本地别名。
  • 🧬 儿童范围: 每次迭代都会获得自己的子作用域,这就是为什么在循环内部赋值原始值不会影响到父级的原因。
  • ???? 身份 Tracking: A track by 表达式告诉 AngularJS 如何识别项目,当集合包含重复值时,它是必需的。
  • 🔢 内置本地化: 在每次迭代中,都可以使用 $index、$first 和 $last 等属性进行编号和样式设置。
  • ⚠️ 支持状态: AngularJS 已于 2021 年 12 月 31 日停止维护,不再接收安全补丁。

AngularJS ng-repeat 指令

AngularJS 中的 ng-repeat 指令

ng-重复 指示 在 AngularJS 中,ng-repeat 用于显示控制器中定义的重复值。有时我们需要在视图中显示一个项目列表,ng-repeat 会将控制器中定义的列表渲染到视图页面上。

⚠️ 支持通知: AngularJS 已达到 生命终结日期为2021年12月31日 并且不再接收任何补丁或安全修复。以下指令对于维护现有的 AngularJS 1.x 应用程序仍然有效;在现代系统中,该指令不再适用。 角度方向 等效物是 *ngFor 结构指令。

AngularJS ng-repeat 指令示例

让我们来看一个AngularJS中ng-repeat指令的例子:

AngularJS 中的 ng-repeat 指令

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
</head>
<body>
<h1>Guru99 Global Event</h1>
<script src="https://code.angularjs.org/1.8.3/angular.js"></script>

<div ng-app="DemoApp" ng-controller="DemoController">
    <h1>Topics</h1>
    <ul>
        <li ng-repeat="tpname in TopicNames">
            {{tpname.name}}
        </li>
    </ul>
</div>

<script>
    var app = angular.module('DemoApp', []);

    app.controller('DemoController', function($scope) {
        $scope.TopicNames = [
            { name: "What controllers do from Angular's perspective" },
            { name: "Controller Methods" },
            { name: "Building a basic controller" }
        ];
    });
</script>

</body>
</html>

Code 说明:

  1. 调节器首先,我们定义要在视图中显示的列表项数组。这里是一个名为 TopicNames 包含三个项目,每个项目都是一个名称-值对。
  2. 数组直接赋值给 $scope.TopicNames这样,它就可供绑定到此控制器的视图使用。
  3. HTML标签 <ul> (无序列表) <li> (列表项)显示列表项。ng-repeat 指令会遍历数组中的每个条目,并且 tpname 是保存当前项的局部变量,所以 {{tpname.name}} 打印其名称属性。

⚠️更正: 最初的解释指出,该数组“被添加到一个名为”的成员变量中。 topics代码中不存在这样的变量——数组直接被赋值给了 $scope.TopicNames这是视图所指的名称。在此处引入第二个名称是导致列表为空的常见原因。

如果代码执行成功,浏览器中将显示以下输出。

AngularJS 中的 ng-repeat 指令

AngularJS 多个控制器

之前我们看到过一个单独的控制器,其中一个方法同时处理加法和减法。trac数字的处理。您可以使用多个控制器来更清晰地分离逻辑。例如,一个控制器可以处理数字,而另一个控制器可以处理字符串。

让我们来看一个在 AngularJS 应用程序中定义多个控制器的例子。

AngularJS 多个控制器

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
</head>
<body>
<h1>Guru99 Global Event</h1>
<script src="https://code.angularjs.org/1.8.3/angular.js"></script>

<div ng-app="DemoApp">
    <div ng-controller="firstcontroller">
        <div ng-controller="secondcontroller">
            {{lname}}
        </div>
    </div>
</div>

<script>
    var app = angular.module('DemoApp', []);

    app.controller('firstcontroller', function($scope) {
        $scope.pname = "firstcontroller";
    });

    app.controller('secondcontroller', function($scope) {
        $scope.lname = "secondcontroller";
    });
</script>

</body>
</html>

Code 说明:

  1. 定义了两个控制器, firstcontrollersecondcontroller每个变量都附加到自己的 范围: pname 首先, lname 在第二。
  2. 从视图中可以看出,第二个控制器嵌套在第一个控制器内部,表达式为: lname 从内部作用域来看。因为嵌套控制器继承自其父控制器, {{pname}} 这里也能得出同样的结论——遗产是向下传承的,绝不会向上传承。

如果代码执行成功,则文本 第二控制器 被展示。

AngularJS 多个控制器

使用方法 track 通过 ng-repeat

ng-repeat 最常见的故障是以下错误 Duplicates in a repeater are not allowed当集合中包含两个相同的值时,就会出现此错误,并且它会完全停止列表渲染。

原因在于身份认同 tracAngularJS 需要为每个项目分配一个稳定的键,以便重用 DOM 节点,而不是在每次摘要时都重建它们。默认情况下,它使用项目值本身,因此两个相同的值会发生冲突。

<!-- Fails: the value 2 appears twice -->
<li ng-repeat="n in [1, 2, 2, 3]">{{n}}</li>

<!-- Works: position is unique even when values repeat -->
<li ng-repeat="n in [1, 2, 2, 3] track by $index">{{n}}</li>

<!-- Best for records from a server: track by a real identifier -->
<li ng-repeat="topic in TopicNames track by topic.id">{{topic.name}}</li>

在这两种形式之间做出选择比乍看起来更重要。 Tracking by $index 这种方法总能解决错误,因为位置根据定义是唯一的,但它将每个 DOM 节点绑定到一个插槽而不是记录。重新排序或过滤集合会重用错误的节点,这会导致输入字段出现问题。ping 上一行的文本。

Tracking 通过真实有效的标识符,例如 topic.id 完全避免了这个问题。AngularJS 可以跟踪每个记录的移动,因此它会重新排列现有节点,而不是销毁并重建它们。对于长列表,这种方法也明显更快,因为重新渲染只会影响实际更改的行。 $index 仅适用于永不重新排序的纯值数组。

ng-repeat 内部提供的特殊属性

ng-repeat 的每次迭代都会在其自身的子作用域中暴露几个只读属性。这些属性描述了当前项在集合中的位置,涵盖了编号、交替样式和分隔符等信息,而无需向控制器添加任何额外的状态。

特性 类型 价值
$index 联系电话 当前项的位置,从 0 开始
$first 布尔 仅对第一个项目成立
$last 布尔 仅对最后一个项目成立
$middle 布尔 对于既非首项也非末项的每个项目,此结论成立。
$even 布尔 当 $index 为偶数时为真
$odd 布尔 当 $index 为奇数时为真

一个典型的用法是将它们与 ng-class 结合使用,用于斑马纹ping,如在 ng-class="{'row-alt': $odd}"或者使用 ng-if 来为除最后一行之外的每一行渲染分隔符,如下所示 ng-if="!$last"显示易于理解的行号非常简单 {{$index + 1}}由于索引是从零开始的,因此每当集合发生变化时,所有六个属性都会自动重新计算,无需手动重新计算任何内容。

常见的 ng-repeat 错误及解决方法

大多数 ng-repeat 问题都源于重复值、作用域继承或指令放置在错误的元素上。以下每个症状都列出了其原因。

  • 中继器中不允许出现重复项: 集合中包含重复值。添加 track by $index, 或更好, track by 一处独特的房产。
  • 列表没有任何显示: 视图中的名称与作用域中的属性不匹配。打印集合。 {{TopicNames}} 确认已送达。
  • 所有元素都会重复出现,包括外层元素: ng-repeat 被放在了容器上,而不是元素上。请将其移动到容器上。 <li> or <tr>.
  • 编辑输入内容时,更改了错误的行: 列表如下: trac被 $index 商品重新排序期间。 Track 改为使用稳定的标识符。
  • 循环内部的更改不会保留: 每次迭代都有自己的子作用域,因此写入基本类型会创建一个本地副本。写入对象属性,例如 item.done.

常见问题

是的,使用 ng-repeat="(key, value) in myObject"请注意,AngularJS 是按排序顺序而不是插入顺序遍历对象键的,因此当顺序很重要时,使用数组更安全。

表达式中的链式过滤器,例如 ng-repeat="t in TopicNames | filter:search | orderBy:'name'"原始数组保持不变;只有渲染顺序和子集发生变化。

是的。 AI 工具将 ng-repeat 映射到 *ngFor 和 track 由到 trackBy 函数。请仔细检查过滤器,因为 Angular 特意移除了内置的 filter 和 orderBy 管道。

AI 工具会发现重复表达式内部的函数调用(这些函数调用会在每次摘要时重新运行),并且会遗漏某些内容。 track 子句会强制重建整个 DOM。这两种情况通常都会导致列表加载缓慢。

请使用评论表单。 ng-repeat-startng-repeat-end它会重复一系列同级元素。这在表格中很重要,因为多一个 div 元素会破坏表格的标记。

总结一下这篇文章: