【问题标题】:Angular - What is the point of implementing trackBy?Angular - 实施 trackBy 有什么意义?
【发布时间】:2018-05-30 08:14:33
【问题描述】:

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

  • 在这个blog 中实现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 跟踪对我来说有意义吗?我真的应该在每个带有 *ngFor 的组件中实现 return index;-function 吗?

【问题讨论】:

    标签: angular ngfor angularjs-track-by


    【解决方案1】:

    *ngFor 按对象标识跟踪项目,并在更新迭代数组时为数组中的项目更新迭代数组时尝试避免重新渲染元素,而更新之前数组中的位置已经在数组中。

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

    *ngFor 覆盖字符串列表,如

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

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

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

    另见

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

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

    【讨论】:

    • 感谢您的深入解释。看起来我还没有 trackBy 有用的用例。我只会将 codelyzer 标志设置为 false。我觉得奇怪的是默认情况下不是 false,考虑到 ngFor 无处不在,而且这些情况非常具体。
    • 我认为使用trackBy 并不常见。我认为上面提到的案例相当少见。
    猜你喜欢
    • 1970-01-01
    • 2018-11-19
    • 1970-01-01
    • 2015-03-18
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    • 2018-01-15
    相关资源
    最近更新 更多