我的印象是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将替换为“默认值”价值“即使模型保持正确。”
答案 0 :(得分:1)
*ngFor
按对象标识跟踪项目。
如果你有像字符串数组这样的原始值,并在
中使用它们<div *ngFor="let item of items; let i=index">
<input [(ngModel)]="item" name="item{{i}}">
</div>
并且您编辑了一个项目,然后*ngFor
遇到了麻烦,因为已编辑项目的标识已更改。
使用ngForTrackBy
,您可以告诉*ngFor
按索引跟踪项目,然后在编辑字段时,上面的代码可以正常工作。
另一个用例是当你希望*ngFor
通过某个自定义对象id属性而不是对象标识来跟踪项目时。