knockout.js 如何仅使用DOM对象获得leaflet.js示例?

x6492ojm  于 2022-11-10  发布在  其他
关注(0)|答案(2)|浏览(140)

我现在正在构建一个自定义Knockout.js绑定来处理多边形的绘制。在本例中,Knockout API只给了我一个对DOM对象的引用,以访问我需要更新的任何内容。然而,看起来leaflet.js的设计是希望用户在他们的实现中存储Map示例。我没有这个选项。
尝试此操作时出现错误:var existingMap = L.map('aMapIDGoesHere')
错误是:map already initialized .
有什么方法可以使用DOM元素或元素ID来访问Map示例吗?
根据要求,这里的自定义绑定,请注意这是一个正在进行中的工作:

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 
  }
};

特别注意你会注意到我正在把点转换成一个连接的字符串。这暂时是必要的。

plicqrtu

plicqrtu1#

只要你确定DOM元素不会被删除,你就可以把它作为DOM元素本身的一个子属性来添加。下面是一个绑定处理程序,它使用传单首页上的代码来设置传单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);
    }
};

要使用绑定处理程序,只需按如下方式进行绑定:

<div data-bind="leaflet: { latitude: latitudeProperty, longitude: longitudeProperty, zoom: zoomProperty }"></div>

只要确保你也设计了div,以确保它有一个高度和宽度。我已经写了a jsfiddle which uses the above leaflet bindingHandler,你可以尝试一下。
我只在Internet Explorer 11、Firefox 26.0和Firefox 27.0.1中测试过这个jsfidle。

1cklez4t

1cklez4t2#

注意到在非常有限的情况下,这可能是一种解决方案:https://stackoverflow.com/a/60836683/1116657

window[Object.keys(window).find(key => key.substr(0,3) === "map")];

阅读我最初的帖子,了解它的脆弱性和局限性,但我认为这对某些人可能会有帮助。谢谢!

相关问题