我给人的印象是,仅在尝试优化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被删除,则执行以下步骤:


删除第一项
添加一个新项目


在这种情况下,第一项的输入将替换为第二项的内容(两个字段都具有相同的内容),但是,模型中的值是正确的。

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

我真的很感谢任何解释。如果这不是问此类问题的合适地点,请将我重定向到正确的位置。谢谢。

更新

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

最佳答案

默认情况下,*ngFor通过对象标识跟踪项目。

如果您具有诸如字符串数组之类的原始值,请在

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


并且您编辑一项,则*ngFor会遇到麻烦,因为已编辑项的标识已更改。

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

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

关于javascript - Angular 2-trackBy函数,它实际上是做什么的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43262089/

10-10 05:33