我不是Angular 4的专家,我一直在使用Angular 4构建应用程序。因此,由于我不清楚,因此我试图了解变更检测功能。目前,我在ChangeDetectorRef.detectChanges()方法中使用ngAfterViewInit。可以说我有一个示例UI组件,它是这样的:

<div>{{state}}</div>


我在类中有两个变量,分别是statestateUpdater。我的stateUpdater:

this.state = 0;
setInterval(() => {
    this.stateUpdater = 0;
    if (this.stateUpdater % 8 === 0) {
      this.state = this.stateUpdater;
    }
    this.stateUpdater++;
}, 100);


因此,对于这种情况,stateUpdater将每100 ms更新一次,而state将每800 ms更新一次。我的问题是,“ detectChanges”函数将每100毫秒调用一次以更新UI吗?否则,将每800毫秒调用一次吗?

如果每100毫秒调用一次,该如何防止这种行为?因为这对于UI透视图是完全无效的。

我将不胜感激任何建议。谢谢。

最佳答案

生命周期适用于整个组件或指令。

区域setInterval触发更改检测,而不更改stateUpdater值。

如果某些代码段中不希望进行某些更改检测,则可以通过使用runOutsideAngular评估当前区域的代码超大容量来局部禁用它。 run可以在本地重新启用它:

ngZone.runOutsideAngular(() => {
  setInterval(() => {
    if (this.stateUpdater % 8 === 0) {
      ngZone.run(() => {
        // yes! change detection
        this.state = this.stateUpdater;
      });
    }
    // no change detection
    this.stateUpdater++;
  }, 100);
});


或者,可以在需要时手动触发更改检测:

zone.runOutsideAngular(() => {
  setInterval(() => {
    if (this.stateUpdater % 8 === 0) {
      // yes! change detection
      this.state = this.stateUpdater;
      changeDetectorRef.detectChanges();
    }
    // no change detection
    this.stateUpdater++;
  }, 100);
});


可以使用detach暂时禁用更改检测,并使用reattach启用更改检测。它们的影响不是局部的,整个组件都会受到影响:

  setInterval(() => {
    if (this.stateUpdater % 8 === 0) {
      changeDetectorRef.reattach();
      // yes! change detection
      this.state = this.stateUpdater;
    } else {
      // no change detection
      changeDetectorRef.detach();
      this.stateUpdater++;
    }
  }, 100);


变更检测是一种相对低成本的操作,这就是其存在的原因。如果绑定到视图的属性中未检测到任何更改,则该视图将不会更新。

由于变更检测是框架的基本组成部分,因此应该在大多数情况下使用它,而对其进行细粒度的控制则违反了使用框架的目的,并且可以被认为是过早的优化,除非另有证明。

为了使不会导致视图更改的更改检测周期不对性能造成重大影响,视图绑定不应太昂贵。

08-19 00:12