禁用更改检测传播到父级

时间:2019-12-17 08:34:30

标签: angular angular2-changedetection

在标题组件中,我显示当前时间并每秒更新一次。自从改变时间 不影响任何其他组件,我不希望Angular对整个组件图每秒进行更改检测。似乎每秒,Angular不仅会在父组件上运行更改检测,还会在不在标头组件到根组件(sidenav和maincontent)的路径上的组件上运行更改检测。

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

  • CD HeaderComponent
  • CD MainContentComponent
  • CD SideTreeComponent
  • CD主视图
  • CD MainContentComponent
  • CD SideTreeComponent
  • CD主视图

我尝试了onpush策略,每秒调用一次detectChanges()。不论是否有ChangeDetectorRef.detach()

我在做什么错?如何禁用整个树更改检测运行以及从根到头组件更改检测的路径。

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}} 

1 个答案:

答案 0 :(得分:0)

找到了答案。重新运行更改检测不是由detectChanges()触发的,而是由setInterval方法触发的,因为此方法是由Zone修补的。

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

对我有用的解决方案是:

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