我给人的印象是,仅在尝试优化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/