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