禁用更改检测传播到 parent

Disable change detection propagation to parent

在我的 header 组件中,我显示当前时间并每秒更新一次。自从换了时间 不影响任何其他组件,我不希望 Angular 到 运行 每秒对整个组件图进行更改检测。每一秒,似乎 Angular 运行 的变化检测不仅在 parent 组件上,而且在不在从 header 组件到根组件的路径上的组件上(sidenav和主要内容)。

通过在其他 3 个组件的模板(sidenav、maincontent 和 mainview)中使用 getter {{runChangeDetection}},我在开发工具中看到每秒打印这 7 行:

我尝试使用每秒调用 detectChanges() 的 onpush 策略。也有和没有 ChangeDetectorRef.detach().

我做错了什么?如何禁用整个树变化检测 运行 和从根到 header 组件变化检测的路径。

header.ts:

  changeDetection: ChangeDetectionStrategy.OnPush
})
export class HeaderComponent implements OnInit {
  get runChangeDetection() {
    console.log('CD HeaderComponent');
    return true;
  }
  public time :Date = new Date()
  constructor(private cdr: ChangeDetectorRef){
    this.cdr.detach()
  }

  ngOnInit() {
    setInterval(() => {
      this.time = new Date()
      this.cdr.detectChanges()
    }, 1000)
  }
}

header.html:

<mat-toolbar>
  <div class="time">{{time | date: 'HH:mm:ss'}}</div>
</mat-toolbar>
{{runChangeDetection}} 

找到答案了。重新运行 变化检测不是由detectChanges() 触发的,而是通过setInterval 方法触发的,因为该方法已被Zone.

您可以通过删除带有 detectChanges() 的行来检查,即使没有更改任何值,更改检测也会重新运行。

对我有用的解决方案是:

    this.ngZone.runOutsideAngular(() => {
      setInterval(() => {
        this.time = new Date()
        this.cdr.detectChanges()
      }, 1000)
    })