Angular ngDoCheck() gets called even with ChangeDetectionStrategy.OnPush

时间:2017-08-05 11:53:23

标签: angular angular2-changedetection

Lets say i have a component structure like this:

AppComponent
    HeaderComponent
    ContentComponent
        TodosComponent
            TodoComponent

If I set HeaderComponent's changeDetection to ChangeDetectionStrategy.OnPush and change something in TodoComponent, still HeaderComponent's ngDoCheck(), ngAfterViewChecked() and ngAfterContentChecked() gets triggered.

What am I missing? Does ngDoCheck gets triggered anyway? If yes, how to determine if a component was checked by ChangeDetection?

1 个答案:

答案 0 :(得分:6)

是的,这是正确的行为。文章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部分。它显示了您正在寻找的操作顺序。

另请阅读Why do we need ngDoCheck