vue-leaflet / Vue2Leaflet

Vue 2 components for Leaflet maps
https://vue2-leaflet.netlify.app
MIT License
1.96k stars 380 forks source link

Popup Moving underlying data is replaced. #600

Closed Steve-Groner closed 4 years ago

Steve-Groner commented 4 years ago

Description

I am using the marker code code below, inside is an array activeAircraftMarkers and then every 10 seconds I overwrite the data in the activeAircraftMarkers array. The issue is that when I have the popup open and the activeAircraftMarker data changes, the popup may jump to a different marker. I literally add all the markers and then delete and readd them every 10 seconds. I have no idea why this is happening. I have a feeling that because I replace the data each time and not update it, that this may be why. Is there some leaflet ID changing or something. If I just update the data in the array instead of replacing it do you think that would solve the issue?

     <l-marker v-for="(marker, index) in activeAircraftMarkers" v-bind:key="index" :lat-lng="marker.point" :icon="marker.icon" :options="marker.options">
          <l-popup :content="marker.popup" :options="marker.popup_options" />
          <l-tooltip :content="marker.tooltip_content" :options="marker.tooltip_options"></l-tooltip>
</l-marker>

Here is a sample of one of the markers:

{
    "id": "NXXXX",
    "point": {
      "lat": 34.226602,
      "lng": -116.569176
    },
    "popup_options": {
      "maxHeight": 250,
      "maxWidth": 350,
      "keepInView": true,
      "autoPan": false,
      "autoClose": false
    },
    "popup": "<div style='text-align: center;'><table><tr style='height: 35px;'><td colspan='2' style='text-align: center; font-weight: bold; font-size: 14px; color: white; background-color: #0000FF;'>CAP485</td></tr><tr style='height: 10px;'><td>&nbsp;</td></tr><tr><td style='text-align: left;'><strong>Call Sign:&nbsp;&nbsp;</strong></td><td style='text-align: left;'>CAP485</td></tr><tr><td style='text-align: left;'><strong>Tail Number:&nbsp;&nbsp;</strong></td><td style='text-align: left;'>N285CP</td></tr><tr><td style='text-align: left;'><strong>Flight #:&nbsp;&nbsp;</strong></td><td style='text-align: left;'>2</td></tr><tr><td style='text-align: left;'><strong>Lat:&nbsp;&nbsp;</strong></td><td style='text-align: left;'>34.226602</td></tr><tr><td style='text-align: left;'><strong>Lon:&nbsp;&nbsp;</strong></td><td style='text-align: left;'>-116.569176</td></tr><tr><td style='text-align: left;'><strong>Alt:&nbsp;&nbsp;</strong></td><td style='text-align: left;'>069</td></tr>",
    "tooltip_content": "<div>CXXXXX</div>",
    "tooltip_options": {
      "permanent": true,
      "custom": true,
      "direction": "top",
      "offset": [
        0,
        -19
      ],
      "opacity": 1,
      "className": "tooltipBox"
    },
    "icon": {
      "options": {
        "iconUrl": "../images/ca/marker-180.png",
        "iconSize": [
          46,
          46
        ],
        "className": "markerIconZIndex"
      },
      "_initHooksCalled": true
    }
  },

Live Demo

No Live Demo

Steps to Reproduce

N/A

Expected Results

I expect that when I have a popup open for a marker that the popup stay with the marker.

Actual Results

A popup will be open but it may be a popup for a different marker.

Browsers Affected

Versions

elmatou commented 4 years ago

Hi,

First thing, your screencast needs a password to play, and your code needs three backquotes to display nicely .

Then, your intuition seems to be good. With Vuejs, you need to think data, and not UI, in that case, Object and not leaflet marker.

If you want to update the UI, update the data, do not change the object it relies on, here activeAircraftMarkers is an Object/Array and the reference should not change. Just change the content. if it is too complicated to change the data in place, try with a computed property, Vuejs do a very good change in updating only the changing data.

Maybe you could use templating to set the content of your icon, popup and tooltip, it is quite efficient and allow you to remove all the html you put in your data <l-popup>Hello {{marker.id}}!</l-popup>

Steve-Groner commented 4 years ago

Thank you for the response. I did add the backtick, but apparently not enough of them. My apologies. I removed the video, but I uploaded (2) versions and removed the password on the 2nd, not sure why it still asked for it. But, I appreciate you reading between the lines here. I did update my code to MODIFY the data instead of REPLACE it and it indeed did solve the problem. I like the idea of templating, so I assume I just pass the data fields I want instead and then just use them inside {{ }} calls to put them in the right place. That will save alot of time loading these into the map. I will give that a try. Thank you once again I appreciate you taking the time to answer me.

elmatou commented 4 years ago

I'm gad you solved your problem.

Templating is a Vuejs thing, just get the guides and API reference and you'll get it. Vue2Leaflet just leverage the thing for popup/tooltip/... content, as if you were using a function as content (leaflet already implemented the templating strategy in some way)

DonNicoJs commented 4 years ago

@elmatou Thank you for helping @Steve-Groner I think we can close this!