MelihAltintas / vue3-openlayers

Web map Vue 3.x components with the power of OpenLayers
https://vue3openlayers.netlify.app/
MIT License
689 stars 128 forks source link

Passing a reactive variable to `ol-geom-line-string` coordinate no longer stays in sync with variable. #387

Open marktlinn opened 2 weeks ago

marktlinn commented 2 weeks ago

Describe the bug I have a component that is making use of <ol-geom-line-string> e.g. <ol-geom-line-string :coordinates="coordinateArray"></ol-geom-line-string> passing a ref containing an array of coordinate arrays to the ol-geom-line-string.

In the initial versions of our app we had been using Vue3 OpenLayers version 4.0.2 and the reactivity worked as expected. On pushing a new coordinate to the ref coordinateArray the new values were being reflected in the geom line being extended to match the values in the Vue ref. Now that is not the case.

Affected version(s)

Please run npm list --depth=0 vue vue3-openlayers ol ol-ext ol-contextmenu and paste the output below: ├── ol-contextmenu@5.5.0 ├── ol-ext@4.0.23 ├── ol@10.1.0 ├── vue@3.5.3 └── vue3-openlayers@11.2.1

Vue3-openlayers: "11.2.0" (also tested on "11.2.1")
Node:  v20.10.0

To Reproduce Steps to reproduce the behavior: Create a geom-line-string element and pass :coordinate a array of coordinates that has a new coordinate pushed to it as some set interval.

On the map as the reactive variable coordinateArray has most coordinates pushed to it they should be shown on the map.

Expected behavior The expected behaviour is that when passed a reactive variable containing coordinates the reactive variable is updated (e.g. additional coordinates are pushed to the array) these updates should be reflected in the map with the geom-line growing, shrinking etc.

Desktop (please complete the following information):

d-koppenhagen commented 2 weeks ago

I think it's cause the property is not watched deeply. Have you tried to pass a new reference instead of directly pushing into the existing one?

Like this:

const coordinates = ref([/* ... */])

// ...

coordinates.value = [...coordinates.value, newValue]
marktlinn commented 2 weeks ago

Thank you for your response.

Yes, passing a new reference works and is what we're currently doing, but when tracking a large growing array it leads to inefficiencies in needing to copy and create a new reference each time versus a simple .push() operation on an existing array. The Vue reactivity system supports tracking appending elements to an array via the push method as well as supporting other array methods.

This worked in prior versions of Vue3 OpenLayers so was it intentionally removed, or is there an option to have it watched deeply? It feels like if such reactivity is supported natively by Vue it would be great if there were at least an option to enable deep watch.

d-koppenhagen commented 2 weeks ago

So, I don't think it was removed intentionally. Does it make a difference when you switch from ref to reactive?

marktlinn commented 2 weeks ago

No, unfortunately not, it doesn't draw or update the <ol-geom-line-string>.