Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Marker with dynamic content #32

Open
mazvv opened this issue Nov 3, 2019 · 2 comments
Open

Marker with dynamic content #32

mazvv opened this issue Nov 3, 2019 · 2 comments

Comments

@mazvv
Copy link

mazvv commented Nov 3, 2019

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.

Peek 2019-11-03 16-10

@holtolee
Copy link

holtolee commented May 12, 2020

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.

@MatthiasAT
Copy link

MatthiasAT commented Jul 14, 2020

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>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants