技术背景
数据无涡轮链接
请注意,仅将属性添加data-no-turbolink="true"
到链接会抑制该链接的 turbolinks。单击该链接会加载整个页面,而不是用 turbolinks 替换内容。
但是有几种方法可以在不抑制 turbolink 的情况下将 turbolink 与 gmaps4rails 一起使用。
Turbolinks 回调
使用 turbolinks 的关键是使用提供的回调。在这种情况下,当 turbolinks 加载新页面时,必须告诉 gmaps4rails 执行地图加载。
一般来说,可以使用$(document).on('page:load', function ... )
,例如Railscast #390中所示。
JavaScript 的同源策略
gmap4rails gem 包含的google api 脚本从 google 静态服务器请求另一个脚本。但是如果 api 被 turbolinks 动态包含,那么单源策略会阻止对 google 静态服务器的请求。
单源策略本身就是一个有用的东西。尽管有几种方法可以规避它,但这似乎不是一件自然的事情。相反,“正确的方法”是“证明”网页确实想要执行远程脚本(google api)并且远程脚本不是由恶意脚本请求的。这是通过在 html 树中包含直接请求 google api 的脚本标记来完成的。
在使用 turbolinks 时,只有在第一次请求时才能将 google api script 标签直接包含在 html 树中,因为所有以后的更改都是通过 turbolinks 动态注入到树中的。这意味着,当使用 turbolinks 时,即使在不显示地图的页面上也必须包含 google api。
解决方案 1(推荐):为 gmaps4rails 使用 fork
我提出了一个拉取请求,希望为 gmaps4rails 添加 Turbolinks 支持。
演示
如果您愿意,请先看一下这个演示,它显示了 gmaps4rails 与 turbolinks 的使用:
如何在您的项目中使用它
您可以通过将 fork 添加到 Gemfile 来尝试一下并检查它是否适用于您的项目:
# Gemfile
# ...
gem 'turbolinks'
gem 'gmaps4rails', '~> 2.0.1', git: 'https://github.com/fiedl/Google-Maps-for-Rails.git'
# ...
此外,您需要修改布局文件以将 api 包含在 html 头中:
<!-- 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>
如果由于某种原因你不想使用这个 fork,我看到了两种使用 gmaps4rails 和 turbolinks 的替代方案:
解决方案 2:手动执行
基本上做与fork相同的事情(解决方案1),可以手动将api脚本添加到布局文件的头部。然后,当通过 turbolinks 加载页面时,可以使用 javascript 配置和激活地图。
这通常在 gmaps4rails wiki 中与 UJS 一起使用:
https ://github.com/apneadiving/Google-Maps-for-Rails/wiki/Using-with-UJS
解决方案 3:手动包含 api 静态信息
如果您不想全局添加 api 脚本,有一种方法可以绕过单源策略并动态加载 api。
我为此准备了一个要点:https ://gist.github.com/fiedl/6573175
您必须添加一个执行两件事的 javascript 文件:
- 加载谷歌地图 api本身。
- 加载静态文件,该文件由 api 加载。
您可以通过在浏览器中打开api 脚本getScript
并从底部的调用中复制 url 来找到静态文件的 url 。
但是:这样做会修复对您的语言环境的静态 api 请求,如果您的应用程序在国际上使用,这可能不是一件好事。