Angular 2 - trackBy函数,它真正起作用了什么?

时间:2017-04-06 17:33:22

标签: javascript angular

我的印象是trackBy函数仅在尝试优化*ngFor的性能时使用,因此如果更改了某些内容,则不必重建DOM。

然而,最近,我遇到了trackBy实际修复错误行为的情况。

以此为例:https://plnkr.co/edit/nRgdwoiKAMpsbmWaoMoj?p=preview 专注于爱好部分,尤其是HTML:

<div>
  <h2>Hobbies</h2>
  <div *ngFor="let h of user.hobbies; trackBy:customTrackBy; let i = index">
    #{{i}} - {{h | json}}<br />

    <input [(ngModel)]="h.name" name="hobby_name_{{i}}" /> <br /><br />

    <select [(ngModel)]="h.type_id" name="type_{{i}}">
      <option *ngFor="let t of types" [value]="t.id">{{t.type}}</option>
    </select>

    <br />
    <br />
    <button class="btn btn-warn" (click)="remove(i)">Remove</button>
    <br /><br />
  </div>
</div>

我必须在第一个trackBy:customTrackBy中明确定义此部分:*ngFor。如果删除trackBy,则执行以下步骤:

  1. 删除第一项
  2. 添加新项目
  3. 在这种情况下,第一个项目的输入将替换为第二个项目的内容(两个字段具有相同的内容),但是,模型中的值是正确的。

    trackBy解决了这个问题,但为什么呢?

    我真的很感激任何解释。如果这不是提出这类问题的正确位置,请将我重定向到正确的问题。感谢。

    更新

    以下是错误行为的示例:https://plnkr.co/edit/u8YajKfHcPiVqY0WcJt7?p=preview删除第一项(循环)并添加新项(添加按钮)并查看两个值如何获得相同的默认值(BF将替换为“默认值”价值“即使模型保持正确。”

1 个答案:

答案 0 :(得分:1)

默认情况下,

*ngFor按对象标识跟踪项目。

如果你有像字符串数组这样的原始值,并在

中使用它们
<div *ngFor="let item of items; let i=index">
  <input [(ngModel)]="item" name="item{{i}}">
</div>

并且您编辑了一个项目,然后*ngFor遇到了麻烦,因为已编辑项目的标识已更改。

使用ngForTrackBy,您可以告诉*ngFor按索引跟踪项目,然后在编辑字段时,上面的代码可以正常工作。

另一个用例是当你希望*ngFor通过某个自定义对象id属性而不是对象标识来跟踪项目时。