简体   繁体   中英

Making a rails 7 stimulus controller handle values dynamically

while leaflet can be installed and a map generated, with

./bin/importmap pin leaflet

manually adding the leaflet.css file to assets/stylesheets and images to the public/images directory,

a stimulus controller is set with static values.

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = [ "placeholder" ]

  connect(){
    import("leaflet").then( L => {
      this.map = L.map(this.placeholderTarget,{zoomDelta:0.5,zoomSnap:0.5}).setView([ 47.1960, 9.023 ], 10);

      var base_map = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
      }).addTo(this.map);
      var marker1 = L.marker([47.4, 8.9]).addTo(this.map);
      var marker2 = L.marker([47.0, 9.3]).addTo(this.map);
    });
  }

  disconnect(){
    this.map.remove()
  }

}

The coordinates will be elsewhere on the page.

How should this controller then be cast assuming the document will have an id for 'lat_1', 'lon_1', 'lat_2', 'lon_2', 'zoom', 'lat_marker_1', 'lon_marker_1', 'lat_marker_2', 'lon_marker_2'

This is an XY problem. It goes to say that for pretty much any programming langauge/framework that if you're using identifiers (variable names, ids, attribute etc) that end with _n you're doing it wrong and should be using a list/array/map/hash/object instead.

If you want to pass a bunch of Map markers through the DOM just use an element such as a list and data attributes:

<ul id="cities">
  <li data-lat="40.781944" data-lon="-73.966111">New York</li>
  <li data-lat="19.076111" data-lon="72.87751">Mumbai</li>
  <li data-lat="50.45" data-lon="30.523333">Kyiv</li>
</ul>

This mostly makes sense if your displaying the same data on the page in for example a table. Otherwise you might want to consider setting up a route which provides the data as JSON.

You can also use custom elements if you want like vue-leaflet does .

If you then want to add these markers to the map you just loop through the elements:

let cities = document.getElementById('cities');
for (const city of cities.children) {
  let marker = L.marker([city.dataSet.lat, city.dataSet.lon]);
  marker.addTo(this.map);
}

Remember that you don't have to assign ids to everything in the DOM and building your JS like that isn't a good way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM