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

时间:2017-02-15 08:56:28

标签: arrays angular ngfor

假设我们有一系列项目:

items = [
    { title: 'item 1'},
    { title: 'item 2'},
    /* ... */
];

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

<ul>
    <li *ngFor="let item of items">{{item.title}}</li>
</ul>

如果我通过push / splice添加/删除项目,或者只添加/删除相应项目的标记,那么wle 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;

2 个答案:

答案 0 :(得分:16)

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

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

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

enter image description here

点击Paint Flashing选项,让您的列表变得有趣 如果某个区域呈绿色闪烁,则表示已经涂漆/重新涂漆。

EX:如果你在Gunter的回答中使用Plunkr:http://plnkr.co/edit/oNm5d4KwUjLpmmu4IM2K?p=preview并切换Paint Flashing,请在列表中添加一个项目,您会看到之前的项目没有闪烁。 (这意味着没有重画)。

答案 1 :(得分:13)

,仅当数组本身被其他数组实例替换时才会重新渲染。

<强>更新

感谢OlivierBoissé(见评论)

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

另见StackBlitz example

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

在这个问题的答案中,掠夺者展示的动画How can I animate *ngFor in angular 2?也证明了这一点。事实上,这种动画是以这种方式实现这一点的驱动因素(除了一般优化)