即使在调用map.invalidateSize()

时间:2018-03-23 19:20:00

标签: angular ngx-leaflet

我遇到了一个问题,其他人似乎都遇到了我的ngx-leaflet地图没有完全呈现的地方,直到我调整大小。我试图以多种方式调用map.invalidateSize(),例如在ngOnInit,onMapReady中,以上所有的超时。 I get this on the initial load。我正在使用ngx-leaflet 2.5,因为3.0+不能工作角4.4.5。

访问模态的按钮是

<app-map
  (closeButtonClicked)="mapModal.hide()"
  class="modal fade"
  bsModal
  #mapModal="bs-modal"
  tabindex="-1"
  role="dialog"
  aria-labelledby="mySmallModalLabel"
  aria-hidden="true"
  [Service]="Service"></app-map>

css是:

@import '../../app';
#map {
  color: white;
  font: 1em 'Dosis', Arial, sans-serif;
  width: 90vh;
  margin: 30px auto;
  button.close {
    font-size: 30px;
    opacity: .4;
  }
  .modal-dialog {
    width: 100vw;
    height: 50vw;
    .devices-sm({
      width: 90vh;
      height: 70vh;
    });
    .modal-content {
      height: 100%;
      .modal-body {
        height: 100%;
        background-color: @accent-background-color;
        padding: 0;
        #map {
          height: 100%;
          width: 100%;
          padding: 0;
        }
      }
    }
  }
}

这是实际地图的代码

googleHybrid = L.tileLayer('http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', {
    maxZoom: 20,
    subdomains: ['mt0', 'mt1', 'mt2', 'mt3'],
    detectRetina: true
});
options = {
    layers: [
        this.googleHybrid
    ],
    zoom: 1.49,
    center: L.latLng([180, -180]),

};

2 个答案:

答案 0 :(得分:1)

Leaflet对地图的大小非常敏感。这意味着只要您显示/隐藏地图,就需要确保调用invalidateSize()方法。使用ngx-bootstrap模式,正确的时间将在onShown事件处理程序中。

我已经创建了ngx-leaflet-tutorial-ngcli GitHub项目[1]的一个分支,它展示了如何使这个工作。虽然这个例子适用于ng5和ngx-leaflet @ 3,但同样的方法适用于ng4和ngx-leaflet @ 2.

[1] https://github.com/Asymmetrik/ngx-leaflet-tutorial-ngcli/compare/develop...ngx-bootstrap-modal-demo

相关摘录如下。

在您的组件中,为onShown事件添加处理程序:

handleOnShown() {
   this.map.invalidateSize();
}

在模板中,设置(onShown)输出以调用处理程序:

<button type="button" class="btn btn-primary"
        (click)="staticModal.show()">
  Show a Map
</button>

<div class="modal fade"
     bsModal #staticModal="bs-modal"
     [config]="{backdrop: 'static'}"
     tabindex="-1" role="dialog"
     aria-labelledby="mySmallModalLabel" aria-hidden="true"
     (onShown)="handleOnShown()">

  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title pull-left">Static modal</h4>
        <button type="button" class="close pull-right"
                aria-label="Close"
                (click)="staticModal.hide()">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <div class="map"
             leaflet
             (leafletMapReady)="onMapReady($event)"
             [leafletOptions]="options"
             [leafletLayersControl]="layersControl"></div>
      </div>
    </div>
  </div>
</div>

答案 1 :(得分:0)

/* // In style.css add this class map */
.map {
  position: relative !important;
  width: 100%; height: 600px;
  margin: 2px;
  padding: 2px;
}

/*--------------------------------------------------------------------*/

// In Angular component .ts file

import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import * as L from 'leaflet';

@Component({
  selector: 'app-map-control',
  template: 
    `<div class="map" leaflet
      (leafletMapReady)="onMapReady($event)"
      [leafletOptions]="options"
      (leafletMouseOver)="refreshMap()"
      style="border: black solid 1px;">
    </div>`
})

export class MapControlComponent {

  constructor() { }

  public map: L.Map = null;
  private latoLong: L.LatLngTuple = [35.706000, 51.4025000]; // for set static lat-long to map


  // Define our base layers so we can reference them multiple times
  streetMaps = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    detectRetina: true,
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
  });

  // Set the initial set of displayed layers (we could also use the leafletLayers input binding for this)
  options = {
    layers: [this.streetMaps],
    zoom: 17,
    center: L.latLng(this.latoLong)
  };

  @Output() outputLatLong = new EventEmitter<L.LatLngTuple>();

  refreshMap() {
    if (this.map) {
      // this.streetMaps.redraw();
      this.map.invalidateSize();
    }
  }

  onMapReady(map: L.Map) {
    map.on('click', (eventMouse: L.LeafletMouseEvent) => {
      this.latoLong = [eventMouse.latlng.lat, eventMouse.latlng.lng];
      map.setView(this.latoLong, map.getZoom());
      this.outputLatLong.emit(this.latoLong);
    });
    this.map = map;
  }

}