vue2-leaflet-markercluster
vue2-leaflet-markercluster copied to clipboard
Marker with dynamic content
Hi! I have some problems with markers that has dynamic content. My code is:
<template>
<div>
<div class="flex flex-col flex-wrap -mx-2 h-full relative">
<div class="px-2 min-h-screen">
<l-map
ref="map"
:zoom="zoom"
:center="placeLatLng"
:options="mapOptions"
@update:bounds="updateBounds"
class="rounded-lg">
<l-tile-layer
:url="url"
:attribution="attribution"></l-tile-layer>
<vue2-leaflet-markercluster
:options="{
chunkedLoading: true,
animate: false,
}">
<l-marker v-for="(car, i) in cars.page.filter(x => x.place)"
:lat-lng="{ ...car.place }" :key="`place_${i}`"
:options={car}
@click="showPopup">
<l-popup>
<div class="w-48">
<car :car="car" v-if="popups.includes(car.id)"></car>
</div>
</l-popup>
<l-icon>
<div :class="car.tmr ? 'text-green-700' : 'text-blue-800'">
<svgicon name="pin" class="w-6"
color="#ffffff inherit inherit"></svgicon>
</div>
</l-icon>
</l-marker>
</vue2-leaflet-markercluster>
</l-map>
</div>
</div>
</div>
</template>
.....
showPopup: function (e) {
const { car } = e.target.options
if(!this.popups.includes(car.id))
this.popups.push(car.id)
}
If marker outside the cluster this code works fine, but when cluster spiderify click on marker simply collapse cluster. See image bellow.
I have the exactly same problem, did you resolve it since you wrote the issue?
Edit: I just found a workaround. Cluster don't like popup with dynamic content, you need to extend your component from LPopup and catch the popupopen event to update it's content like this:
let self = this
let marker = this.$refs[markerRef].mapObject
marker.on('popupopen', function (e) {
// Get your extended component and call it's "refresh" function mad by you
let popup = self.$refs[popupRef]
popup.setOpen(params...)
})
To extend from LPopup just add this to your component:
import * as Vue2Leaflet from 'vue2-leaflet'
export default {
extends: Vue2Leaflet.LPopup,
....
And of course instead of using <l-popup>
use your component's name.
Hope it helps other devs. Maybe there is a better fix.
Hi, I'm facing exactly the same problem and haven't found another solution yet.
@holtolee: Thanks for your workaround. Unfortunately I'm having problems to figure out where and how to overwrite the popupopen event. I assume, I have to put your code somewhere in my custom popup component that is extending LPopup but don't know how. May I kindly ask you to further explain this, maybe based on an example?
Thank you very much in advance!
Update
Thanks to @holtolee I got I working for me, though a bit different. I'm sure there might still be a better solution, but this worked for me.
New custom popup component:
<template>
...
<!-- Dynamic content part that caused issues when used in "original" l-popup in a markercluster: -->
<v-layout column v-if="item.id == currentId">
...
</v-layout>
..
</template>
<script>
import * as Vue2Leaflet from 'vue2-leaflet'
export default {
extends: Vue2Leaflet.LPopup,
name: 'CustomPopup',
props: {
item: Object,
},
computed: {
currentId() {
return this.$store.state.currentId;
},
},
}
Parent component with map and markercluster:
<template>
...
<l-marker-cluster>
<!-- I did not use the @click event, but defined a custom method for the @popupopen event of the marker: -->
<l-marker v-for="item in markers" :key="item.id" @popupopen="openMarkerPopup(item)">
<CustomPopup :item="item" />
</l-marker>
</l-marker-cluster>
...
</template>
<script>
...
import CustomPopup from './CustomPopup';
...
export default {
components: {
...
// LPopup, <-- not required any more
CustomPopup,
...
},
...
methods: {
openMarkerPopup(item)
{
<!-- Setting the currenId that is used as a condition for the dymanic part of the popup content. In my case I don't have
to explicitly call marker.openPop() again, as the popup is anyways opening... -->
this.$store.commit('setCurrentId', id);
},
},
...
</script>