angular - ngFor, trackby
ngFor
ngForOf指令通常使用缩写形式*ngFor为集合中的每个项呈现模板的结构指令。该指令放置在元素上,该元素将成为克隆模板的父级。
<li *ngFor="let item of items; index as i; trackBy: trackByFn">...</li>
一般使用是:
const list = [{age: '16'}, {age: '18'}, {age: '15'}] <li *ngFor="let item of list; index as i>{{item.age}}</li> // 或者 <li *ngFor="let item of list; let i = index">{{item.age}}</li>
使用trackBy提高性能
trackBy: trackByFn 定义如何跟踪iterable中项的更改的函数。
在iterable中添加、移动或移除项时,指令必须重新呈现适当的DOM节点。为了最小化DOM中的搅动,只重新呈现已更改的节点。
默认情况下,更改检测器假定对象实例标识iterable中的节点。提供此函数时,指令使用调用此函数的结果来标识项节点,而不是对象本身的标识。
函数接收两个输入,迭代索引和节点对象ID。
要想自定义默认的跟踪算法,NgForOf
支持 trackBy
选项。 trackBy
接受一个带两个参数(index
和 item
)的函数。
如果给出了 trackBy
,Angular 就会使用该函数的返回值来跟踪变化。
@Component({ selector: 'my-app', template: ` <ul> <li *ngFor="let item of list;">{{item.age}}</li> <li *ngFor="let item of list;trackBy: trackByFn">{{item.age}}</li> </ul> <button (click)="getItems()">Refresh items</button> `, }) export class App { list = [{age: '16'}, {age: '18'}, {age: '15'}]; constructor() { this.list= [{age: '16'}, {age: '18'}, {age: '15'}] } getItems() { this.list= [{age: '16'}, {age: '18'}, {age: '15'}, {age: '80'}] } trackByFn(index, item) { return item.age; // or index } }
列表发生变化是,如果没有添加 trackBy , 那么与数据关联度的所有DOM元素会重新渲染;
如果使用trackBy :更改列表时,Angular可以根据唯一标识符跟踪已添加或删除的项目,并仅创建或销毁已更改的项目。
局部变量
const list = [{age: '16'}, {age: '18'}, {age: '15'}]; <li *ngFor="let item of list; first as isFirst">{{item.age}} <span *ngIf="isFirst">岁</span> </li> /* 16岁 18 15 */
NgForOf
导出了一系列值,可以指定别名后作为局部变量使用:
-
$implicit: T
:迭代目标(绑定到ngForOf
)中每个条目的值。 -
ngForOf: NgIterable<T>
:迭代表达式的值。当表达式不局限于访问某个属性时,这会非常有用,比如在使用async
管道时(userStreams | async
)。 -
index: number
:可迭代对象中当前条目的索引。 -
first: boolean
:如果当前条目是可迭代对象中的第一个条目则为true
。 -
last: boolean
:如果当前条目是可迭代对象中的最后一个条目则为true
。 -
even: boolean
:如果当前条目在可迭代对象中的索引号为偶数则为true
。 -
odd: boolean
:如果当前条目在可迭代对象中的索引号为奇数则为true
。