【问题标题】:How can I create an ionic popover from a leafletjs polygon?如何从leafletjs 多边形创建离子弹出框?
【发布时间】:2018-12-04 06:25:19
【问题描述】:

我正在使用 Leaflet JS 在地图上绘制多边形。

我能够绘制形状,并将形状作为 GeoJSON 保存到数据库,如下所示:

.ts 文件

...
    let layer = event.layer;
    let geometry = layer.toGeoJSON();
    this.drawLayer.addLayer(layer);
}

我在ngOnInit 方法中调用一个方法来重绘形状:

drawPolygonShape(data) {
    if (data.polygon.geometry) {
        let shape = {
            type: data.polygon.type,
            geometry: {
                type: data.polygon.geometry.type,
                coordinates: data.polygon.geometry.coordinates
            },
            properties: {}
        };

        L.geoJSON(shape, {
            onEachFeature: this.onEachFeature
        }).addTo(this.myMap);
    }
}


...


onEachFeature(feature, layer) {
    layer.on('click', event => {
        // layer.bindPopup('Hello World'); // Works great
        let popover = this.popoverCtrl.create('MyComponent', { layer: layer });
        popover.present();
    });
}

我正在将MyComponent 导入到模块文件中,所以我知道它是可用的。但是,我总是收到以下错误消息:

无法读取未定义的“创建”属性

因此,某处存在时间或范围问题,无法正确处理点击事件。

这似乎是一个范围问题,因为任何组件都会给出相同的错误。任何建议都非常感谢!

编辑

感谢@ghybs 我已尝试将this 作为点击事件的第三个参数添加,但我仍然遇到同样的错误:

    onEachFeature(feature, layer) {
    layer.on('click', event => {
        // layer.bindPopup('Hello World'); // Works great
        let popover = this.popoverCtrl.create('MyComponent', { layer: layer });
        popover.present();
    }, this);
}

编辑 2

谢谢@ghybs!

我很好奇您的第二个建议 - 我正在这样设置地图:

let mapOptions: any = {
    position: 'topright',
    draw: {
        polyline: false,
        ...
    }
}

...

let drawControl = new L.Control.Draw(mapOptions);
this.myMap.addControl(drawControl);

this.myMap.on(L.Draw.Event.CREATED, this.onCreatePolygon.bind(this));

.bind(this) 现在更有意义了 - onCreatePolygon 是我用来保存形状的一种方法。

你建议我如何委托给每个形状的点击事件?

this.myMap.on(L.Draw.Event.CLICK, this.MYCLICKHANDLER.bind(this));

(很明显我不熟悉这个工作,所以我很感谢你所有的时间。)

【问题讨论】:

标签: javascript leaflet ionic3


【解决方案1】:

在您的情况下,您有一个 double 上下文问题,因为您还传递了您的 onEachFeature 方法,该方法将使用已经与您的类实例不同的 this 上下文调用。

您可以将onEachFeature: this.onEachFeature.bind(this) 与您的layer.on("click", cb, this) 一起使用

您还可以通过将侦听器附加到您的 GeoJSON 图层组而不是每个单独的功能上来使用事​​件委托,这样您就可以摆脱其中一个上下文:

var geoJsonData = {
  "type": "Point",
  "coordinates": [2.35, 48.86]
};

class Component {
  constructor(mapId) {
    this.myMap = L.map(mapId).setView([48.86, 2.35], 11);

    L.geoJSON(geoJsonData).addTo(this.myMap).on("click", event => {
      console.log(event.target); // this is the GeoJSON Layer Group.
      console.log(event.layer); // this is the individual child feature.
      let popover = this.popoverCtrl.create('MyComponent');
      popover.present();
    }, this); // Not even needing the 3rd arg since you use a fat arrow function, which does not have its own context.

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(this.myMap);
  }
}

Component.prototype.popoverCtrl = { // Dummy popoverCtrl
  create(content) {
    dummyPopoverContent = content;
    return {
      present() {
        alert(dummyPopoverContent);
      },
    };
  },
};

var dummyPopoverContent = '';

new Component('map');
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>

<div id="map" style="height: 180px"></div>

另见start a function when click on circle - leaflet


至于你的最后一个问题,上面的第一句话你可以重写:

this.myMap.on(L.Draw.Event.CREATED, this.onCreatePolygon.bind(this));

进入:

this.myMap.on(L.Draw.Event.CREATED, this.onCreatePolygon, this);

在这种情况下,事件委托似乎无关紧要,因为您已经在地图上附加了一个单个侦听器,而不是在单个图层上。

【讨论】:

  • 你太棒了。非常感谢你的解释。我很想知道你的第二种方法。我认为这类似于我设置要绘制的地图的方式。我已经更新了我的问题以将其包含在最后。你的建议类似吗?
  • 查看带有 Leaflet 层组的事件委托的代码示例。我不确定我是否完全理解你的最后一个问题,希望编辑后的答案能解决这个问题。
  • 非常感谢您的所有时间。你帮了我很大的忙!
猜你喜欢
  • 1970-01-01
  • 2020-07-23
  • 1970-01-01
  • 2018-12-13
  • 1970-01-01
  • 2012-01-05
  • 2019-08-10
  • 2021-09-01
  • 1970-01-01
相关资源
最近更新 更多