角5:如何知道我的地图正确加载到所有组件的构造函数中?

时间:2018-07-23 05:42:47

标签: typescript angular5 openlayers-3

我有一个mapservice( maps.service.ts ),其中我编写了一些代码来加载地图,例如

loadMap(target: string, extent?: number[], proj?: string) {
      var self = this;
      this._mapExtent = !extent ? [372728.74434305, 2677793.4448, 378257.6623, 2682126.61080438] : extent;
      this.projection = proj || this.projection;

      this._map = new OlMap({
        layers: [
          new OlTileLayer({
            source: new olSourceOSM()
          }),
          //  layerWFS
        ],
        target: target,            
        view: new OlView({
          center: this._mapExtent,
          projection: this.projection,
          maxZoom: 19,
          zoom: 13
        })
      });

      return new Promise((resolve, reject) => {
        this._map.once('postrender', function (map) {
          self.isMapLoaded = true;
          resolve(map);
        })
      });
      //return this._map.once('postrender').map(res => res.json());
    }

getMap()方法来获取整个应用程序中的地图实例,

getMap() {
          return this._map;
        }

但是在另一个控制器的构造函数中,我需要订阅地图更改事件,像这样

constructor(){
  self.mapService.getMap().on('moveend', (evt) => {
      if (self.undoRedo === false) {
        if (self.size < self.navHistory.length - 1) {
          for (var i = self.navHistory.length - 1; i > self.size; i--) {
            self.navHistory.pop();
          }
        }
        self.navHistory.push({
          extent: self.mapService.getMap().getView().calculateExtent(self.mapService.getMap().getSize()),
          size: self.mapService.getMap().getSize(),
          zoom: self.mapService.getMap().getView().getZoom()
        });
        self.size = self.size + 1;
      }

    });
}

但是问题是,构造函数在映射加载之前加载,并且map正在获得undefined,对于这种情况,有人可以提出最佳实践吗?我是否需要使getMap()方法返回promise并始终调用getMap()。then()?

1 个答案:

答案 0 :(得分:0)

简短的答案是:调用构造函数时,尚无可见的组件。这就是为什么“地图”未定义的原因。看一下OnInit钩子。那就是您想做这类事情的地方。根据实现方式的不同,您可能会使用Observables。基本上,您的getMap应该返回一个Observable,并且您的控制器在其构造函数中对其进行订阅。像这样:

constructor(){
  self.mapService.getMap()
    .subscribe(map => map.on('moveend', (evt) => {
      //your code here
      }))
}

更一般的说明:为什么要将可见组件包装到服务中?服务不是为了这个目的。您可能应该考虑创建一个包装OL的Map-Component。