ngFor指令是否在每个突变上重新呈现整个数组?

adm*_*max 16 arrays ngfor angular

假设我们有一系列项目:

items = [
    { title: 'item 1'},
    { title: 'item 2'},
    /* ... */
];
Run Code Online (Sandbox Code Playgroud)

并且有一个呈现此数组的模板:

<ul>
    <li *ngFor="let item of items">{{item.title}}</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

如果我通过push/ 添加/删除项目,splice或者只添加/删除相应项目的标记,那么angular2会重新渲染整个数组吗?如果它只是更新,那么变异stategies是否有任何区别 - 我是否更喜欢推/拼接而不是阵列替换?换句话说,这两种方法在渲染性能方面是否相同:

/* 1: mutation */
this.items.push({ title: 'New Item' });

/* 2: replacement */
var newArray = this.items.slice();
newArray.push({ title: 'New Item' });

this.items = newArray;
Run Code Online (Sandbox Code Playgroud)

max*_*992 19

除了Gunter的答案,如果你想知道你的UI的哪个部分被渲染/重新渲染你可以使用Chrome(甚至独立于任何lib /框架):

  • 打开调试面板
  • 菜单(调试面板)/更多工具/渲染

然后,您应该看到以下面板:

在此输入图像描述

切换Paint Flashing选项,并对列表有一些乐趣.
如果某个区域呈绿色闪烁,则表示已涂漆/重新涂漆.

EX:如果你在Gunter的答案中使用Plunkr:http://plnkr.co/edit/oNm5d4KwUjLpmmu4IM2K?p=preview 并Paint Flashing打开,将项目添加到列表中,您将看到之前的项目不闪烁.(这意味着没有重画).


Gün*_*uer 15

,只有当数组本身被不同的数组实例替换时,它才会重新呈现.

更新

感谢OlivierBoissé(见评论)

即使传递了不同的数组实例,Angular也会识别它是否包含相同的项实例,即使这样也不会重新渲染.

另请参见StackBlitz示例

如果IterableDiffer使用者在开头或中间识别并添加或删除,则在该位置插入/移除项目而不重新呈现所有其他项目.

Plunkers在这个问题的答案中展示了动画如何在角度2中设置动画*ngFor?也证明了这一点.事实上,这种动画是以这种方式实现这一点的驱动因素(除了一般优化)

  • [https://stackblitz.com/edit/angular-dncqm2](https://stackblitz.com/edit/angular-dncqm2),检查前两个`<p>`你会发现它们没有重新渲染 (2认同)