如何只使用DOM对象获取leaflet.js实例? [英] How can I get a leaflet.js instance using only a DOM object?
问题描述
我现在正在构建一个自定义的Knockout.js绑定来处理多边形的绘制。在这种情况下,Knockout API只给我一个DOM对象的引用来访问我需要更新的内容。但是,看起来像设计leaflet.js希望用户将map实例存储在它们的实现中。我没有那个选项。
I'm right now building a custom Knockout.js binding to handle drawing of polygons. In this case the Knockout API only gives me a reference to a DOM object to access whatever it is I need to update. However, it looks like by design leaflet.js wants the user to store the map instance in their implementation. I don't have that option.
尝试这个给了我一个错误: var existingMap = L.map('aMapIDGoesHere')
Trying this gave me an error: var existingMap = L.map('aMapIDGoesHere')
错误是:地图已初始化
。
我可以使用DOM元素或元素ID来访问地图实例吗?
Any way I can use a DOM element or element ID to access the map instance?
根据请求这里是自定义绑定,请注意这是一项工作正在进行中:
By request here's the custom binding, please note it's a work in progress:
ko.bindingHandlers.leafletDraw = {
init: function(element, valueAccessor, allBindingsAccessor) {
var map = L.map(element).setView([40, -90], 3);
var tiles = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: 'OSM',
minZoom: 2
}).addTo(map);
// Initialise the FeatureGroup to store editable layers
var editableLayers = new L.FeatureGroup();
map.addLayer(editableLayers);
// Initialise the draw control and pass it the FeatureGroup of editable layers
var drawOptions = {
edit: {
featureGroup: editableLayers,
remove: false
},
draw: {
polyline: false,
circle: false,
marker: false,
polygon: {
allowIntersection: false,
showArea: true
}
}
}
var drawControl = new L.Control.Draw(drawOptions);
map.addControl(drawControl);
// when a shape is first created
map.on('draw:created', function (e) {
var shapeString = $.map(e.layer._latlngs, function(pair) { return pair.lng.toString()+"::"+pair.lat.toString(); }).join(";;;");
var value = valueAccessor();
if (ko.isObservable(value)) {
value(shapeString);
}
editableLayers.addLayer(e.layer);
drawControl.removeFrom(map);
drawOptions.draw.polygon = false;
drawOptions.draw.rectangle = false;
var editControl = new L.Control.Draw(drawOptions);
map.addControl(editControl);
});
// handle when a shape is edited
map.on('draw:edited', function (e) {
var editedLayer = e.layers._layers[Object.keys(e.layers._layers)[0]];
var shapeString = $.map(editedLayer._latlngs, function(pair) { return pair.lng.toString()+"::"+pair.lat.toString(); }).join(";;;");
var value = valueAccessor();
if (ko.isObservable(value)) {
value(shapeString);
}
});
},
update: function(element, valueAccessor) {
// need to figure this out since we can't access leaflet params from
}
};
特别提示你会注意到我正在将点转换为连接点串。暂时这是必要的。
Special Note You'll notice that I am converting points into a concatenated string. This is necessary for the time being.
推荐答案
只要你确定不会删除DOM元素,你就可以只需将其添加为DOM元素本身的子属性即可。这是一个绑定处理程序,使用传单首页上的代码来设置传单映射:
As long as you are sure that the DOM element will not be removed, you could just add it as a subproperty on the DOM element itself. Here's a binding handler using the code on the leaflet front page for setting up the leaflet map:
ko.bindingHandlers.leaflet = {
init: function(element, valueAccessor){
var map = L.map(element);
element.myMapProperty = map;
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
},
update: function(element, valueAccessor){
var existingMap = element.myMapProperty;
var value = ko.unwrap(valueAccessor());
var latitude = ko.unwrap(value.latitude);
var longitude = ko.unwrap(value.longitude);
var zoom = ko.unwrap(value.zoom);
existingMap.setView([latitude, longitude], zoom);
}
};
要使用绑定处理程序,您只需绑定如下:
To use the binding handler you would just bind like the following:
<div data-bind="leaflet: { latitude: latitudeProperty, longitude: longitudeProperty, zoom: zoomProperty }"></div>
确保你还设置了 div
确保它有高度和宽度。我已经写了一个使用上面的传单bindingHandler 的jsfiddle,你可以尝试一下。
Just ensure that you have also styled the div
to ensure it has a height and width. I have written a jsfiddle which uses the above leaflet bindingHandler where you could try it out.
我只在Internet Explorer 11,Firefox 26.0和Firefox 27.0.1中测试了这个jsfiddle。
I have only tested this jsfiddle in Internet Explorer 11, Firefox 26.0 and Firefox 27.0.1.
这篇关于如何只使用DOM对象获取leaflet.js实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!