Angular 即使使用 ChangeDetectionStrategy.OnPush 也会调用 ngDoCheck()
Angular ngDoCheck() gets called even with ChangeDetectionStrategy.OnPush
假设我有这样的组件结构:
AppComponent
HeaderComponent
ContentComponent
TodosComponent
TodoComponent
如果我将 HeaderComponent 的 changeDetection
设置为 ChangeDetectionStrategy.OnPush
并更改 TodoComponent 中的某些内容,仍然会触发 HeaderComponent 的 ngDoCheck()
、ngAfterViewChecked()
和 ngAfterContentChecked()
。
我错过了什么? ngDoCheck 是否会被触发?如果是,如何判断某个组件是否被 ChangeDetection 检查过?
是的,这是正确的行为。文章 If you think ngDoCheck
means your component is being checked — read this article 详细解释了该行为。这是简短的版本。
ngDoCheck
在检查组件 之前 被触发。这样做是为了允许您执行一些自定义逻辑,然后标记组件以进行检查。您知道 Angular 通过对象引用跟踪 @Input
,但您可以使用 ngDoCheck
进行自定义跟踪。这是一个简单的例子:
Component({
...,
changeDetection: ChangeDetectionStrategy.OnPush
})
MyComponent {
@Input() items;
prevLength;
constructor(cd: ChangeDetectorRef) {}
ngOnInit() {
this.prevLength = this.items.length;
}
ngDoCheck() {
if (this.items.length !== this.prevLength) {
this.cd.markForCheck();
}
}
请记住,ngDoCheck
仅针对具有策略 OnPush
的顶级组件触发。它不会为此组件子项触发。
此外,即使现在已完成检查,也会为组件触发 ngAfterViewChecked
是正确的。这也是设计使然。
我强烈建议您阅读 Everything you need to know about change detection in Angular,特别是 Exploring the implications
部分。它显示了您要查找的操作顺序。
另请阅读。
假设我有这样的组件结构:
AppComponent
HeaderComponent
ContentComponent
TodosComponent
TodoComponent
如果我将 HeaderComponent 的 changeDetection
设置为 ChangeDetectionStrategy.OnPush
并更改 TodoComponent 中的某些内容,仍然会触发 HeaderComponent 的 ngDoCheck()
、ngAfterViewChecked()
和 ngAfterContentChecked()
。
我错过了什么? ngDoCheck 是否会被触发?如果是,如何判断某个组件是否被 ChangeDetection 检查过?
是的,这是正确的行为。文章 If you think ngDoCheck
means your component is being checked — read this article 详细解释了该行为。这是简短的版本。
ngDoCheck
在检查组件 之前 被触发。这样做是为了允许您执行一些自定义逻辑,然后标记组件以进行检查。您知道 Angular 通过对象引用跟踪 @Input
,但您可以使用 ngDoCheck
进行自定义跟踪。这是一个简单的例子:
Component({
...,
changeDetection: ChangeDetectionStrategy.OnPush
})
MyComponent {
@Input() items;
prevLength;
constructor(cd: ChangeDetectorRef) {}
ngOnInit() {
this.prevLength = this.items.length;
}
ngDoCheck() {
if (this.items.length !== this.prevLength) {
this.cd.markForCheck();
}
}
请记住,ngDoCheck
仅针对具有策略 OnPush
的顶级组件触发。它不会为此组件子项触发。
此外,即使现在已完成检查,也会为组件触发 ngAfterViewChecked
是正确的。这也是设计使然。
我强烈建议您阅读 Everything you need to know about change detection in Angular,特别是 Exploring the implications
部分。它显示了您要查找的操作顺序。
另请阅读