Javascript 如何仅使用DOM对象获取一个传单.js实例?

Javascript 如何仅使用DOM对象获取一个传单.js实例?,javascript,knockout.js,leaflet,knockout-2.0,Javascript,Knockout.js,Leaflet,Knockout 2.0,我现在正在构建一个定制的Knockout.js绑定来处理多边形的绘制。在这种情况下,knockoutapi只提供对DOM对象的引用,以访问需要更新的对象。但是,看起来by design传单.js希望用户将地图实例存储在其实现中。我没有这个选择 尝试此操作时出现错误:var existingMap=L.map('amapidGoesher') 错误是:映射已初始化 是否可以使用DOM元素或元素ID访问映射实例 根据要求,这是定制绑定,请注意这是一项正在进行的工作: ko.bindingHandle

我现在正在构建一个定制的Knockout.js绑定来处理多边形的绘制。在这种情况下,knockoutapi只提供对DOM对象的引用,以访问需要更新的对象。但是,看起来by design传单.js希望用户将地图实例存储在其实现中。我没有这个选择

尝试此操作时出现错误:
var existingMap=L.map('amapidGoesher')

错误是:
映射已初始化

是否可以使用DOM元素或元素ID访问映射实例

根据要求,这是定制绑定,请注意这是一项正在进行的工作:

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

特别注意您会注意到我正在将点转换为串联字符串。这在目前是必需的。

只要您确定DOM元素不会被删除,就可以将其作为子属性添加到DOM元素本身。下面是一个绑定处理程序,使用传单首页上的代码设置传单地图:

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);
    }
};
ko.bindingHandlers.传单={
init:函数(元素、值访问器){
var map=L.map(元素);
element.myMapProperty=map;
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png'{
属性:“©;贡献者”
}).addTo(地图);
},
更新:函数(元素、值访问器){
var existingMap=element.myMapProperty;
var value=ko.unwrap(valueAccessor());
变量纬度=ko.展开(值纬度);
变量经度=ko.展开(值.经度);
var zoom=ko.unwrap(value.zoom);
现有Map.setView([纬度,经度],缩放);
}
};
要使用绑定处理程序,只需按如下方式进行绑定:

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

只需确保您还设置了
div
的样式,以确保它具有高度和宽度。我已经写了你可以尝试的地方


我只在Internet Explorer 11、Firefox 26.0和Firefox 27.0.1中测试过这个JSFIDLE。

注意,在非常有限的情况下,这可能是一个解决方案:


阅读我的原始帖子,对它的脆弱性和局限性发表评论,但我认为这可能会对某些人有所帮助。谢谢

您可以添加您的代码吗?@leszek.hanusz done。代码起作用的部分位于底部的
update
属性下。仅仅使用
元素
无法获取映射实例。哇,从来没有想过将其实际存储在DOM对象本身中。不错的想法:)在我的用例中,如果删除了DOM对象,那么就没有理由进一步访问它。谢谢你!您可能希望查看
ko.utils.domNodeDisposal.addDisposeCallback
,以确保在删除DOM对象时处理映射对象和事件侦听器。类似于
ko.utils.domNodeDisposal.addDisposeCallback(元素,函数(){element.myMapProperty.remove();})
或类似的功能应该可以正常工作。(请注意,此注释中的代码完全未经测试。)
window[Object.keys(window).find(key => key.substr(0,3) === "map")];