7

从最近开始,当您没有在每个 *ngFor 上实现 trackBy-function 时,Angular styleguide-lint-extender“Codelyzer”会发出警告。我想知道为什么这被认为是一个问题。

  • 在此博客中,实现 trackBy 的示例归结为trackByFn(index, item) { return index;} // or item.id. 如果我从 index 切换到 item.id,这将如何使我的应用程序更快?当涉及到数组插入或删除时,索引是最直接的事情。为什么 [ngFor] 指令应该比较对象标识值?
  • 在模块 ng_for_of.d.ts 我可以找到_trackByFn. 所以我假设,return index-trackBy 无论如何都是默认配置?那么为什么明确地实施它被认为是一种好习惯呢?

现在就个人而言,我的应用程序中确实有一个大集合(数组),它位于 redux 商店中。它只能被一个空数组替换,或者可以添加新项目,例如:

return {...state, myArray: [...state.myArray, ...newItems]}),

但从未移动或删除。item.id对我来说跟踪而不是有意义index吗?我真的应该return index;在每个带有 *ngFor 的组件中实现一个 -function 吗?

4

1 回答 1

8

*ngFor通过对象标识跟踪项目,并尝试避免在迭代数组更新数组中的项目时重新呈现元素,而这些项目在更新之前已经在数组中。

如果数组包含原始值(字符串、布尔值、数字),则*ngFor在修改后无法识别它们。

一个*ngFor字符串列表,如

items = ['foo', 'bar', 'baz'];
<input *ngFor="let item of items" [(ngModel)]="item">

当在渲染中修改值时会导致奇怪的行为,<input>因为在每次键盘输入之后,值都会改变并且*ngFor会丢失之前渲染项目的位置,因此删除更改之前值的输入并将其添加到之后的值改变。这会导致输入失去焦点,并可能导致输入改变位置。

要解决此问题,您可以指示*ngFor按索引而不是按身份进行跟踪。

也可以看看

对于对象,它也很有用,例如,如果您想*ngForid属性跟踪项目。这很有用,例如,如果使用了不可变值并且修改了列表中的一项 - 这意味着用具有相同id属性值的新对象实例替换,但其他一些属性发生了变化。指示*ngFor跟踪依据id不会导致项目被删除并重新添加到 DOM。

*ngFor不能正确识别修改过的项目也会导致像这个Plunker 示例中所示的动画(来自How can I animate *ngFor in angular 2?)中断(动画太频繁)。

于 2017-12-16T08:44:56.970 回答