未捕获的TypeError:无法读取属性' _leaflet_id'未定义的VueJs和Leaflet

时间:2018-02-20 19:13:20

标签: javascript vue.js leaflet

我正在制作一个vue项目,我想在我的组件中使用传单。我显示了地图,我可以添加标记但是当我尝试删除标记时遇到错误。我得到了

  

未捕获的TypeError:无法读取属性' _leaflet_id'未定义的    在n(leaflet.js:5)     在e.removeLayer(leaflet.js:5)     在HTMLInputElement.eval(VM119323 App.vue:74)    在HTMLInputElement.dispatch(jquery.js:3058)    在HTMLInputElement.eventHandle(jquery.js:2676)

<template>
 <div id="app" class="container-fluid">
  <div class="row">
   <div class="col-md-9">
    <div id="map" class="map" style="height: 781px;"></div>
  </div>
  <div class="col-md-3">

  </div>
</div>
<router-view/>
</div>
</template>

<script>
export default {
 name: "App",
 data() {
return {
  map: null,
  markers: [],
  mapSW: [0, 4096],
  mapNE: [4096, 0],
  tileLayer: null
 };
 },
mounted() {
this.initMap();
this.initLayers();
this.onClick();
this.onPopupOpen();
},
 computed: {
popupContent: function() {
  return "<input type='button' value='Delete' class='marker-delete-button' /> <br> <input type='button' value='Add Event' class='add-event'/>";
 }
},
 methods: {
initMap() {
  this.map = L.map("map").setView([0, 0], 1);
  this.tileLayer = L.tileLayer("/static/map/{z}/{x}/{y}.png", {
    maxZoom: 4,
    minZoom: 3,
    continuousWorld: false,
    noWrap: true,
    crs: L.CRS.Simple
  });
  this.tileLayer.addTo(this.map);

  this.map.on("click", this.onClick, this);

  this.map.setMaxBounds(
    L.LatLngBounds(L.latLng(this.mapSW), L.latLng(this.mapNW))
  );

},
initLayers() {},
onClick(e) {
  var newMarker = L.marker(e.latlng, {
    draggable: true
  })
    .addTo(this.map)
    .bindPopup(this.popupContent);

  this.markers.push(newMarker);


  newMarker.on("popupopen", this.onPopupOpen, this);
},
onPopupOpen(index) {

  $(".marker-delete-button:visible").click(() => {
    this.map.removeLayer(this.newMarker);


  });
  }
}
};
</script>

2 个答案:

答案 0 :(得分:2)

newMarker变量的范围应属于该组件,以便您以后可以将其删除。现在它只存在于onClick方法中。您可以阅读有关变量范围here的更多信息。为了解决您的问题,您需要将newMarker添加到data()函数:

// ...
data() {
  return {
    // ...
    tileLayer: null,
    newMarker: null
  };
},
// ...
onClick(e) {
  this.newMarker = L
    .marker(e.latlng, { draggable: true })
    .addTo(this.map)
    .bindPopup(this.popupContent);

  this.markers.push(this.newMarker);

  this.newMarker.on("popupopen", this.onPopupOpen, this);
},

onPopupOpen(index) {
  $(".marker-delete-button:visible").click(() => {
    this.map.removeLayer(this.newMarker);
  });
}

您完成的代码将类似于:

<template>
  <div id="app" class="container-fluid">
    <div class="row">
      <div class="col-md-9">
        <div id="map" class="map" style="height: 781px;"></div>
      </div>
      <div class="col-md-3">

      </div>
    </div>
    <router-view/>
  </div>
</template>

<script>
export default {
  name: "App",

  data() {
    return {
      map: null,
      markers: [],
      mapSW: [0, 4096],
      mapNE: [4096, 0],
      tileLayer: null,
      newMarker: null
    };
  },

  mounted() {
    this.initMap();
    this.initLayers();
    this.onClick();
    this.onPopupOpen();
  },

  computed: {
    popupContent: function() {
      return "<input type='button' value='Delete' class='marker-delete-button' /> <br> <input type='button' value='Add Event' class='add-event'/>";
    }
  },

  methods: {
    initMap() {
      this.map = L.map("map").setView([0, 0], 1);
      this.tileLayer = L.tileLayer("/static/map/{z}/{x}/{y}.png", {
        maxZoom: 4,
        minZoom: 3,
        continuousWorld: false,
        noWrap: true,
        crs: L.CRS.Simple
      });
      this.tileLayer.addTo(this.map);

      this.map.on("click", this.onClick, this);

      this.map.setMaxBounds(
        L.LatLngBounds(L.latLng(this.mapSW), L.latLng(this.mapNW))
      );
    },

    initLayers() {},

    onClick(e) {
      this.newMarker = L
        .marker(e.latlng, { draggable: true })
        .addTo(this.map)
        .bindPopup(this.popupContent);

      this.markers.push(this.newMarker);

      this.newMarker.on("popupopen", this.onPopupOpen, this);
    },

    onPopupOpen(index) {
      $(".marker-delete-button:visible").click(() => {
        this.map.removeLayer(this.newMarker);
      });
    }
  }
};
</script>

答案 1 :(得分:0)

您还可以做的是使用hasLayer方法,在删除标记之前验证标记是否确实在地图上,

if (this.map.hasLayer(this.newMarker)) this.map.removeLayer(this.newMarker);