简体   繁体   中英

How to include an url in application.html.erb in rails 6?

I am trying to add Google Map in my rails app. I followed the guidance link: https://medium.com/@pjbelo/using-google-maps-api-v3-with-rails-5-2-b066a4b2cf14 (But I use rails 6) and I have my code: application.html.erb:

  <head>
    <title>GmapTry</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>

    <%= javascript_include_tag 'https://maps.googleapis.com/maps/api/js?key=AIzaSyA7ClwnGU9QTuNhY3DuVqM5K5YbWA7zJsI' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%= yield(:head_tags) %>
  </head>

  <body>
    <%= yield %>
  </body>
<% provide :head_tags do %>
  <meta name='turbolinks-visit-control' content='reload'>
  <script>
    document.addEventListener("DOMContentLoaded", function(){
      initMap(<%=@place.latitude%>, <%=@place.longitude%>)
    });
  </script>
<% end %>
...
...
<p>
    <div id="map"></div>
</p>

places.js

function initMap(lat, lng) {    
    var myCoords = new google.maps.LatLng(lat, lng);    
    var mapOptions = {
        center: myCoords,
        zoom: 14
    };    
    var map = new google.maps.Map(document.getElementById('map'), mapOptions);
}

application.js

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("gmaps/google")
require("packs/places")

Actually when I followed the first step to show the static map, it works well like: 静态地图

but when I go to next step with js, nothing shows up now. Anybody knows why? In rails 6, is there anything wrong to write %= javascript_include_tag 'https://maps.googleapis.com/maps/api/js?key=AIzaSyA7ClwnGU9QTuNhY3DuVqM5K5YbWA7zJsI' % in application.html.erb?

Every maps tutorial I have seen leads to a dead end of inline script tags and globals when its actually really pretty easy to do the job "the right way".

Just use an element with data attributes to pass information from the view to your JavaScript:

<%= content_tag :div, 
                "",
                class: 'google-maps-widget', # call it whatever you want
                data: {
                  lat: @place.latitude,
                  lng: @place.longitude
                }
%>

You can ideally DRY this code into a helper method. Then just setup an event handler that loads the map on the initial page load or when turbolinks refreshes the page .

document.addEventListener("turbolinks:load", function(){
  // find the maps on the page
  let maps = document.querySelectorAll(".google-maps-widget");
  // loop through the maps
  maps.forEach(function(element){
    let data = element.dataset;
    if (!data.initialized) {
      let map = new google.maps.Map(element, {
        // you can just use a object literal instead 
        center: { lat: data.lat, lng: data.lng },
        // lets you override the inital zoom
        zoom: data.zoom || 14 
      });
      // This keeps the element from being re-initialized 
      // if turbolinks persists it
      element.dataset.initialized = "true";
    }
  });
});

If you want to add a bunch of markers to the map you can either just add a bunch of elements inside the <div class="google-maps-widget"... element:

<div class="google-maps-widget" ... >
  <div class="marker hidden" data-lng="1" data-lng="2">My Favorite spot</div>
  ...
<end>

You would then parse these out when initializing the map. Or you add a data attribute to the map element with a URI where you can fetch the markers via AJAX.

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