默认策略下,用户事件,计时器,XHR,promise等事件触发,所有的组件都会执行变更检测。
看一个实际例子:
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'appparentchild',
template: `<h1>title</h1>
{{ JerryHelloChange }}
<child [childContent] = "parentContent"></child>
`
})
export class ParentChildComponent implements OnInit {
public parentContent = 'Jerry 222';
constructor() { }
get JerryHelloChange(){
console.log('change in parent view');
return true;
}
ngOnInit(): void {
this.parentContent = '1';
let c = setTimeout;
setTimeout(() => this.parentContent = '2', 3000);
}
}
@Component({
selector: 'child',
template: `<h1>This is child</h1>
<h2>{{ childContent }}</h2>
<button (click)="onClick()">Click Me to trigger Change</button>
<span>{{ childContent }}</span>`
})
export class ChildComponent{
@Input()
childContent: string;
onClick(){
setTimeout(()=>{ console.log('timeout!')}, 3000);
}
}
测试结果:
测试发现,即使onClick本身的逻辑不会触发任何Component数据的改变,change detection仍然会不断触发。
如果将changeDetectionStrategy改成push:
import { Component, OnInit, Input, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'appparentchild',
template: `<h1>title</h1>
{{ JerryHelloChange }}
<child [childContent] = "parentContent"></child>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ParentChildComponent implements OnInit {
public parentContent = 'Jerry 222';
constructor() { }
get JerryHelloChange(){
console.log('change in parent view');
return true;
}
ngOnInit(): void {
this.parentContent = '1';
let c = setTimeout;
setTimeout(() => {
this.parentContent = '2';
console.log('change in parent');
}, 3000);
}
}
@Component({
selector: 'child',
template: `<h1>This is child</h1>
<h2>{{ childContent }}</h2>
<button (click)="onClick()">Click Me to trigger Change</button>
<span>{{ childContent }}</span>`
})
export class ChildComponent{
@Input()
childContent: string;
onClick(){
setTimeout(()=>{ console.log('timeout!')}, 3000);
}
}
则虽然我在ngOnInit里将this.parentContent改成了2,但是页面仍然没有刷新,仍然是1:
需要点一下按钮才能触发页面刷新:
更多Jerry的原创文章,尽在:“汪子熙”: