Angular.js: $index 使用自定义指令进行 ng-repeat 跟踪

创建于 2017-11-15  ·  3评论  ·  资料来源: angular/angular.js

我提交一个...

  • [ ] 错误报告
  • [ ] 功能要求
  • [X] 其他

当前行为:

在过滤和重复数组之后,每个重复元素中都有一个自定义指令,每个重复元素都有一个独立的范围。 自定义指令不会重新启动。

我认为这是预期的行为,但可能会造成混淆,并且应该更清楚地说明track by $index可以对您的自定义指令做什么。

预期/新行为:
不适用

使用说明最小限度地再现问题:

  1. 在内部使用自定义指令创建 ng repeat(包括 $index 的跟踪)
  2. 在重复数组上使用 $filter 过滤数组,您会注意到指令中的数据不会反映新的过滤数组

AngularJS 版本: 1.5.10

浏览器:全部

还要别的吗:

在使用track by和使用$index和自定义指令不起作用之间,文档能否更清楚地说明 Angular 在做什么。

在此处查看我的回复以了解问题的详细信息
https://stackoverflow.com/a/47310734/2536454

ngRepeat docs

最有用的评论

我相信这确实是预期的行为。 引用文档

当项目重新排序时,它们各自的模板在 DOM 中重新排序。

为了尽量减少 DOM 元素的创建,ngRepeat 使用一个函数来“跟踪”集合中的所有项目及其对应的 DOM 元素。 例如,如果将一个项目添加到集合中,ngRepeat 将知道所有其他项目已经具有 DOM 元素,并且不会重新渲染它们。

在这种情况下(使用track by $index时),第 n 个 DOM 元素将始终与数组的第 n 个项目匹配,因此即使相应项目发生更改,该元素上的绑定也不会更新,本质上会导致视图与基础数据不同步。

综上所述,通过$index进行跟踪会告诉ngRepeat第一项始终相同(因为它具有相同的索引)。 ngRepeat不知道底层数据发生了变化,因为你告诉它只要索引相同,项目就相同(在实践中,通过$index跟踪很少有用) .

由于ngRepeat的东西是相同的,它不会重新创建 DOM,而是保留现有的(绑定到现有的范围等)。 因此,出现在 tempate 上的任何指令都不会被重新编译(因为编译/链接仅在“印出”新实例时发生)。

但我承认我们在文档中解释这一点做得并不好:grin:
@michael-letcher,您有兴趣提交 PR 以改进文档吗?

所有3条评论

任何机会你可以更具体一点(或提供复制样本)?
您可以从这个 plunkr 开始重现问题,因为它似乎对我来说工作正常。

https://plnkr.co/edit/dxzgjmE5MEA0bwQdckVS?p=preview

我相信这确实是预期的行为。 引用文档

当项目重新排序时,它们各自的模板在 DOM 中重新排序。

为了尽量减少 DOM 元素的创建,ngRepeat 使用一个函数来“跟踪”集合中的所有项目及其对应的 DOM 元素。 例如,如果将一个项目添加到集合中,ngRepeat 将知道所有其他项目已经具有 DOM 元素,并且不会重新渲染它们。

在这种情况下(使用track by $index时),第 n 个 DOM 元素将始终与数组的第 n 个项目匹配,因此即使相应项目发生更改,该元素上的绑定也不会更新,本质上会导致视图与基础数据不同步。

综上所述,通过$index进行跟踪会告诉ngRepeat第一项始终相同(因为它具有相同的索引)。 ngRepeat不知道底层数据发生了变化,因为你告诉它只要索引相同,项目就相同(在实践中,通过$index跟踪很少有用) .

由于ngRepeat的东西是相同的,它不会重新创建 DOM,而是保留现有的(绑定到现有的范围等)。 因此,出现在 tempate 上的任何指令都不会被重新编译(因为编译/链接仅在“印出”新实例时发生)。

但我承认我们在文档中解释这一点做得并不好:grin:
@michael-letcher,您有兴趣提交 PR 以改进文档吗?

什么

此页面是否有帮助?
0 / 5 - 0 等级