当用户将鼠标悬停在Openlayers地图上时会重新渲染角度

问题描述 投票:0回答:1

我正在与Angular 8一起在项目中使用Openlayers 6。直到现在,我注意到,只要将鼠标悬停在Openlayers地图上,就会重新渲染地图所在的Angular组件。

我的问题是,如何使父组件始终停止在该悬停上重新渲染。因为它会使应用程序变慢。我的项目中有一个更大的组件,因此,要重新渲染所有内容,将使应用程序本身变慢。

为此,我创建了一个仓库来证明这一点:https://github.com/petrovichm/angular-openlayers-hover-problem。在此示例中,我在html中添加了一个方法,该方法将在运行时进行记录,从而概述了角度重新渲染组件有多少次。

我想用plunker或codesanbox创建在线可运行文件,但是当我制作此示例窗口时,由于重新渲染中存在无穷循环,这使它们不可用,因此冻结了,当我在本地运行此项目时,实际上并不会发生悬停时发生

谢谢。

angular openlayers angular-components openlayers-6 angular-renderer
1个回答
3
投票

克隆您的仓库以查看事物后,有两件事。

首先,用例非常简单,因此您不会看到使用缓解变更检测策略的全部好处,因为该策略可以缓解大多数问题,因为它不会导致非根组件具有变更检测周期(如果所有组件均使用即按即用策略)。

其次,由于基础地图库(OpenLayers)将事件附加到DOM节点本身,由于zone.js拦截了事件处理,因此将触发Angular的更改检测。为避免这种情况,您将不得不在Angular区域之外设置地图:

import { ..., NgZone } from '@angular/core';

...
export class AppComponent implements OnInit {
  ...

  construtor(private zone: NgZone) {
  }

  ...

  ngOnInit() {
    this.zone.runOutsideAngular(() => {
      this.map = new Map({ ... });
    });
  }
}

[在Angular区域以外的地方运行时必须要小心,但是这样做可以防止出现问题。您必须将所有事件处理逻辑都包装回Angular区域,以便Angular知道更新。

export class AppComponent implements OnInit {
  currentValue = 0;

  ...

  ngOnInit() {
    this.zone.runOutsideAngular(() => {
      this.map = new Map({ ... });
    });

    this.map.on('click', (e) => {
      this.currentValue++; // Angular will not pick up this change because it will run outside of the Angular zone
    });

    this.map.on('click', (e) => {
      this.zone.run(() => {
        this.currentValue++; // Angular will pick up this change because it will run inside the Angular zone
      });
    });
  }
}

[这是一篇不错的博客文章,我认为可以进一步帮助您理解这一点:https://netbasal.com/optimizing-angular-change-detection-triggered-by-dom-events-d2a3b2e11d87

© www.soinside.com 2019 - 2024. All rights reserved.