我正在使用gmaps4rails在“客户”节目页面上加载地图。我已经集成了turbolinks以使应用程序更加一致,但是现在我遇到了一个问题,我必须刷新页面以显示地图的地图。我得到的只是一个空白的地图框架。刷新页面时,地图会正确显示。
我尝试添加gem'jquery-turbolinks',但问题仍然存在。
在视图中:
<%= gmaps("map_options" => {:container_class => "map_container_renamed", "zoom" => 15, "auto_zoom" => false},"markers" => { "data" => @json }) %>
在application.js
中//= require jquery
//= require turbolinks
//= require jquery.turbolinks
//= require jquery_ujs
//= require twitter/bootstrap
//= require_tree .
地图空白here的页面来源的要点。
答案 0 :(得分:24)
修复程序最终我需要一个完整的页面加载来刷新脚本。
添加
'data-no-turbolink' => true
转到地图页面的链接。
例如,如果我有一个客户的索引页面,并且我有一个客户端在显示页面上的位置的地图,那么转到显示页面的链接将格式如下:
<%= link_to 'View Client', client, class: "btn", 'data-no-turbolink' => true %>
这将导致html和javascript的完全刷新,而不仅仅是更改的html。
答案 1 :(得分:17)
请注意,只需将属性data-no-turbolink="true"
添加到链接即可停止该链接的turbolink。点击该链接会加载整个页面,而不是用turbolinks替换内容。
但是有几种方法可以使用带有gmaps4rails 的turbolink和来抑制turbolinks。
使用turbolinks获取内容的关键是使用提供的回调。在这种情况下,必须告诉gmaps4rails在turbolinks加载新页面时执行地图加载。
通常,可以使用$(document).on('page:load', function ... )
,例如Railscast #390中所示。
gmap4rails gem包含的google api script请求来自Google静态服务器的其他脚本。但是如果动态链接动态地包含api,则单原始策略会阻止对谷歌静态服务器的请求。
单一来源政策本身是一件有用的事情。虽然有几种方法可以绕过它,但这似乎并不是一件很自然的事情。相反,正确的方式&#34;这样做是为了证明&#34;网页确实想要执行远程脚本(google api)并且恶意脚本不请求远程脚本。这是通过在html树中包含直接请求google api的脚本标记来完成的。
直接在html树中包含google api脚本标记只能在第一次请求时使用turbolinks,因为所有后来的更改都会通过turbolinks动态注入到树中。这意味着,当使用turbolinks时,即使在没有显示地图的页面上也必须包含google api。
我做了一个request,希望增加Turbolinks对gmaps4rails的支持。
如果您愿意,请先查看此演示,了解gmaps4rails与turbolinks的使用情况:
您可以尝试这一点,并通过将分支添加到您的Gemfile来检查它是否适用于您的项目:
# Gemfile
# ...
gem 'turbolinks'
gem 'gmaps4rails', '~> 2.0.1', git: 'https://github.com/fiedl/Google-Maps-for-Rails.git'
# ...
此外,您需要修改布局文件以在html头中包含api:
<!-- app/views/layouts/application.html.erb -->
<html>
<head>
...
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= gmaps4rails_api_script_tags # <-- THIS IS NEW ----------------- %>
<%= csrf_meta_tags %>
</head>
<body>
...
<%= yield %>
<%= yield :scripts %>
</body>
</html>
如果出于某种原因,你不想使用这个分支,我会看到两种方法可以将gmaps4rails与turbolinks一起使用:
基本上与fork(解决方案1)做同样的事情,可以手动将api脚本添加到布局文件中的头部。然后,当通过turbolinks加载页面时,可以使用javascript配置和激活地图。
这通常用于在gmaps4rails wiki中与UJS一起使用: https://github.com/apneadiving/Google-Maps-for-Rails/wiki/Using-with-UJS
如果您不想全局添加api脚本,有一种方法可以绕过单源策略并动态加载api。
我准备了一个要点:https://gist.github.com/fiedl/6573175
您必须添加一个执行两项操作的javascript文件:
您可以通过在浏览器中打开api script并从底部的getScript
调用中复制网址来查找静态文件的网址。
但是:这样做会将静态API请求修复到您的语言环境,如果您的应用在国际上使用,这可能不是一件好事。
答案 2 :(得分:5)
我无法在重新访问已经由turbolinks管理的页面时填充地图画布,尤其是在使用后退按钮时。我通过为turbolinks事件page:load
添加一个侦听器来修复此问题,以映射初始化。
<强> map.js.coffee 强>
google.maps.event.addDomListener(window, 'load', @_setup)
google.maps.event.addDomListener(window, 'page:load', @_setup)
<强> application.js.coffee 强>
//= require jquery
//= require jquery.turbolinks
答案 3 :(得分:0)
可以在此Github issue中找到,您可以在所有网页中加入Google脚本。这解决了Turbolinks没有为新导航的页面执行gmaps4rails javascripts的问题。
请注意,gmaps4rails gem有javascript dependencies,即:
<script src="//maps.google.com/maps/api/js?v=3.13&sensor=false&libraries=geometry" type="text/javascript"></script>
<script src='//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js' type='text/javascript'></script>
您可以通过修改app/views/layouts/application.html.erb
。
<强> application.html.erb 强>
....
<head>
...
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
# insert the following two lines
<script src="//maps.google.com/maps/api/js?v=3.13&sensor=false&libraries=geometry" type="text/javascript"></script>
<script src='//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js' type='text/javascript'></script>
</head>
...
另外,不要忘记通过编辑app/assets/javascripts/application.js
<强>的application.js 强>
添加:
//= require gmaps/google
现在,无需刷新页面即可加载地图。
答案 4 :(得分:0)
我遇到了同样的问题,但我不想关闭turbolinks,我无法正确使用turbolink DOM听众。
在解决另一个问题并重构我的javascript时,我偶然解决了这个问题。
这是我的functions.js
var init_map = function (allMarkers) {
handler = Gmaps.build('Google');
handler.buildMap({ provider: {maxZoom:17, minZoom:5}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(allMarkers());
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
});
};
var marker_check = function(){...};
var init_autocomplete = function () {...};
//function to call google maps functions
var init_google_api = function(function_name){
$(document).ready(function(){
google.maps.event.addDomListener(window, "load", function_name );
});
};
由于我也使用谷歌地方图书馆我有几个功能,我可以用 init_google_api()
打电话在我想要地图的每个视图中,我只需要一个
<%= javascript_tag do %>
init_google_api(init_map(marker_check));
<% end %>
在视图的最后。修复了一切+保持代码干燥,因为想要多个地图等。
如果我没有弄错,这种方法绕过了turbolink问题,因为每次调用一个视图时,它都会执行init_google_api函数和作为参数传入的函数(这就是我使用函数表达式的原因)。因此,每次调用函数时都会运行代码。
答案 5 :(得分:0)
您可以直接从Google地图网址
使用回调<script src="https://maps.googleapis.com/maps/api/js
?callback=yourInitFunction
&key=&sensor=false">
但请注意,在调用此脚本之前,必须先定义init函数。
以下是我的进展方式。我有一个帮助器生成Gmaps脚本标记,其中包含对正确函数的回调(+加载其他gmaps脚本)
# view/your_view.html.erb
<script>
function onGmapsInit() {
// Your code here. You can also define this function in your assets/js directly.
}
</script>
<%= gmap_scripts(callback: 'onGmapsInit') %>
我的助手
# helpers/maps_helper.rb
module MapsHelper
GMAPS_V3_URL = 'https://maps.googleapis.com/maps/api/js'
def gmap_scripts(options = {})
callback = options.delete(:callback)
gmaps_v3_options = {
src: "#{GMAPS_V3_URL}?#{callback ? "callback=#{callback}&" : ''}key=&sensor=false"
}
gmaps_utility_options = {
src: '//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js'
}
capture do
concat content_tag(:script, nil, gmaps_v3_options)
concat content_tag(:script, nil, gmaps_utility_options)
end
end
什么? Turbolinks?这吃东西吗?
我正在使用Turbolinks 5,正如您在此代码中所看到的,您甚至不需要
$(document).on('ready turbolinks:load')