【问题标题】:Call detectChanges in angular zone在角度区域调用detectChanges
【发布时间】:2019-01-06 09:22:39
【问题描述】:

在角度区域外工作时,有两种方法可以检测到变化 - 使用 NgZone.run 或使用 ChangeDetectorRef.detectChanges 方法重新进入区域。 NgZone.run 方法执行应用程序滴答,这可能会导致性能问题,因为它会重新检查整个应用程序。调用 detectChanges 只会更新我需要的组件视图,但是如果组件正在呈现一些它无法控制的内容并且取决于在角度区域中的初始化,它就会停止工作。我创建了一个示例来演示该案例: https://stackblitz.com/edit/angular-zv5mf1?file=src/app/resize.component.ts

单击按钮最初会更新视图。调整窗口大小后,按钮不再更新视图,因为单击处理程序未绑定在角度区域中并且不会触发更改检测。

我的问题是 - 有没有办法只检测组件视图中的更改并初始化角度区域中的内容。换句话说,指定当前区域是角度区域,而不触发应用程序滴答声。

【问题讨论】:

  • 你的例子很好地展示了这个问题,但你能解释一下你想要达到的目标吗?因为如果是这样,我可以告诉你,这不是你在 Angular 中绑定事件的方式......也许有你的目标会让我们为你提供解决这个问题的方法!
  • 我的目标是仅在组件视图中检测更改,然后单击按钮触发更改检测。如果您不想在每次触发事件时对整个应用程序运行更改检测,则必须以这种方式绑定事件。对于更复杂的应用程序而言,在性能方面可能会非常昂贵。
  • 你说的不是真的,我提供了一个答案,告诉你如何去做(因为你花时间回应)。随意看看。

标签: angular


【解决方案1】:

几种解决方案。

第一个是使用事件管理器:stackblitz

this.manager.addGlobalEventListener('window', 'resize', this.setCurrent.bind(this));

第二个是HostListener装饰器:stackblitz

@HostListener('window:resize', ['$event']) private setCurrent(): void {

第三个也是最后一个是全局目标上的模板绑定:stackblitz

template: ` <span [style.display]="'none'" (window:resize)="setCurrent()"></span>

【讨论】:

  • 感谢您的建议。不幸的是,每次触发调整大小事件时,所有建议的解决方案都会触发应用程序范围的检查。如果您将 ngAfterViewChecked 钩子添加到 AppComponent 中,就会出现这种情况:stackblitz.com/edit/angular-zv5mf1-qhtz7e?file=src/app/…
  • 这就是 Angular 的工作原理。 this stackblitz 上的证明(单击按钮更改值)。
猜你喜欢
  • 2019-12-14
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
  • 2015-12-06
  • 2016-12-03
  • 2017-05-12
  • 2021-06-23
  • 1970-01-01
相关资源
最近更新 更多