Gus*_*sta 4 angular2-changedetection angular
我正在学习Angular变化检测过程并检查Chrome中的开发工具,我看到了奇怪的行为.
我的plnkr演示了这种行为:http://plnkr.co/edit/cTLF00nQdhVmkHYc8IOu
我有一个简单的组件与视图:
<li *ngFor="let item of list">{{item.name}}</li>
Run Code Online (Sandbox Code Playgroud)
和构造函数:
constructor() {
this.list = [{name: 'Gustavo'}, {name: 'Costa'}]
Run Code Online (Sandbox Code Playgroud)
模拟我添加的简单请求:
// simulating request repaint the DOM
setInterval( () => {
this.list = [{name: 'Gustavo'}, {name: 'Costa'}];
}, 2000);
Run Code Online (Sandbox Code Playgroud)
如果您注意到,数组list会收到一个等于初始值的列表.让我们假设当Angular在变更检测过程中检查视图中的值时,我们有这样的代码:
if( oldName !== name ) { // ( 'Gustavo' !== 'Gustavo')
// update the view
}
Run Code Online (Sandbox Code Playgroud)
但是值是相同的,为什么角度每2秒重复一次DOM.?

但如果我改变对象,则不会发生REPAINT
// simulating request there is not repaint
setInterval( () => {
this.list[0].name = "Gustavo"; // no repaint because it's the same value
this.list[1].name = "Costa 2"; // repaint
}, 2000);
Run Code Online (Sandbox Code Playgroud)
您可以使用上面的plnkr链接进行测试.
这是因为Angular使用默认值trackByFunction来DefaultIterableDiffer按标识跟踪项目.
const trackByIdentity = (index: number, item: any) => item;
Run Code Online (Sandbox Code Playgroud)
很明显,当您创建一个新数组时,它会创建新的对象引用,而Angular会检测更改.即使您没有更改数组引用,Angular仍会认为项目已更改,因为对象引用更改:
setInterval( () => {
this.list.length = 0;
this.list.push({name: 'Gustavo'});
this.list.push({name: 'Costa'});
}, 2000);
Run Code Online (Sandbox Code Playgroud)
您可以为您提供trackByFunction按对象名称跟踪的自定义:
@Component({
selector: 'my-app',
template: `
<li *ngFor="let item of list; trackBy:identify">{{item.name}}</li>
`
})
export class App {
list:[];
identify(index, item){
return item.name;
}
Run Code Online (Sandbox Code Playgroud)
这样DOM就不会更新.看到这个plunker.
既然你是好奇的,ngFor你也可以阅读这个答案,在那里我解释一下如何ngFor在幕后工作.
| 归档时间: |
|
| 查看次数: |
830 次 |
| 最近记录: |