ngFor 循环列表 保持滚动条位置

522 阅读1分钟

ngFor 如何工作?

ngFor循环的列表发生变化时, ngFor会尽量避免完全重构列表的DOM元素。许多DOM元素会被重用, 这些元素的一些属性值可能会改变。

ngFor默认跟踪列表元素的方式是使用对象标识。这就意味着如果你使用一个和原来列表内容完全一样的新对象, 把新对象传到ngFor,angular是没办法辨别这个对象是不是已经存在的。从对象标识的角度来说,新的列表包含一套全新的内容, 跟原来的列表完全不一样。因为angular不知道应该用什么属性来跟踪对象的变化, 所以这种默认方式是合理的。

弊端:

  1. 在列表很大的情况下(或者列表占了屏幕的很大一部分时), 用这种默认的方式会导致页面加载很慢(很多DOM要被销毁重建)

  2. 如果列表被重新加载, 加载完成后滚动条会跑到列表底部(对用户不友好)

使用 trackBy

使用trackBy我们可以自己定义ngFor的跟踪机制。首先我们要在ngFor里给trackBy传一个函数, 这个函数有两个默认参数(名称可以自己起),如:

  • index   当前循环到的对象的索引

  • item     当前循环到的对象

栗子:

@Component({
   selector: 'heroes',
    template:`
    <table>
        <thead>
            <th>Name</th>
        </thead>
        <tbody>
            <tr *ngFor="let hero of heroes; trackBy: trackHero" >
                <td>{{hero.name}}</td>
            </tr>
        </tbody>
    </table>
    `
    })
    export class Heroes {
        heroes = HEROES;
        trackHero(index, hero) {
            console.log(hero);
            return hero ? hero.id : undefined;
        }
    }

上面这个例子会使用hero的id属性作为ngFor跟踪列表的依据。使用trackBy可以避免上文中的两个使用ngFor默认跟踪机制的弊端。

参考文档: blog.angular-university.io/angular-2-n…