【问题标题】:Angular ngDoCheck() gets called even with ChangeDetectionStrategy.OnPush即使使用 ChangeDetectionStrategy.OnPush 也会调用 Angular ngDoCheck()
【发布时间】:2017-08-05 11:53:22
【问题描述】:

假设我有一个这样的组件结构:

AppComponent
    HeaderComponent
    ContentComponent
        TodosComponent
            TodoComponent

如果我将 HeaderComponent 的 changeDetection 设置为 ChangeDetectionStrategy.OnPush 并更改 TodoComponent 中的某些内容,仍然会触发 HeaderComponent 的 ngDoCheck()ngAfterViewChecked()ngAfterContentChecked()

我错过了什么? ngDoCheck 是否会被触发?如果是,如何判断组件是否被 ChangeDetection 检查?

【问题讨论】:

标签: angular angular2-changedetection


【解决方案1】:

是的,这是正确的行为。文章If you think ngDoCheck means your component is being checked — read this article 非常详细地解释了这种行为。这是简短的版本。

ngDoCheck在检查组件之前触发。这样做是为了允许您执行一些自定义逻辑,然后标记组件以进行检查。您知道 Angular 通过对象引用跟踪 @Inputs,但您可以使用 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

【讨论】:

  • 但是如何确定它是否真的被检查过并且我的 changeDetectionStrategy 工作正常?
  • 对不起,我不明白。仅当 @Input 更改时才会检查您的组件。为什么您需要知道该组件已被检查。我也强烈建议阅读这篇文章以了解该过程
  • 是的,但无法确认它没有被检查?我只能知道但不确定。我阅读了很多文章,我很确定它是如何工作的以及哪些事件会触发 CD。我只是在寻找一种方法来验证组件是否通过 CD 运行。
  • 您有几个选择。例如,您可以使用 timeout 修改 HeaderComponent 中模板中使用的某些值 - 它不会反映在视图中。其他选项是监听子组件上的生命周期钩子 - 不会为它们触发生命周期钩子
  • @Mick 只需在模板中使用 OnPush 添加一些在每个检查视图上执行的代码,例如 {{ testChecking() }} 并观察
猜你喜欢
  • 2022-11-02
  • 2011-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-03
  • 2014-10-29
  • 2014-03-08
相关资源
最近更新 更多