我正在使用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
导入模块文件,因此我知道它可用。但是,我总是收到以下错误消息:
无法读取未定义的属性“创建”
因此,在某个地方存在计时或示波器问题,无法与click事件正确配合。
这似乎是一个范围问题,因为任何组件都会产生相同的错误。任何建议,不胜感激!
编辑
谢谢@ghybs,我尝试将this
作为click事件的第三个参数,但是我仍然遇到相同的错误:
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
是我用来保存形状的一种方法。
您如何建议我将每种形状委托给click事件?
this.myMap.on(L.Draw.Event.CLICK, this.MYCLICKHANDLER.bind(this));
(很明显,我对此并不熟悉,所以感谢您的所有时间。)
答案 0 :(得分: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: '© <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);
在这种情况下,事件委托似乎无关紧要,因为您已经在地图上而非单个图层上附加了单个侦听器。