如何仅使用 DOM 对象获取 Leaflet.js 实例? [英] How can I get a leaflet.js instance using only a DOM object?

查看:19
本文介绍了如何仅使用 DOM 对象获取 Leaflet.js 实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在正在构建一个自定义 Knockout.js 绑定来处理多边形的绘制.在这种情况下,Knockout API 只给我一个 DOM 对象的引用,以访问我需要更新的任何内容.然而,看起来leaflet.js 的设计似乎希望用户在他们的实现中存储地图实例.我没有那个选项.

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')

错误是:map已经初始化.

我可以使用 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: '&copy; <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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆