没有整页刷新,GMaps4Rails和Turbolinks无法加载

Sha*_*aun 12 ruby-on-rails google-maps-api-3 gmaps4rails

我正在使用gmaps4rails在"客户端"显示页面上加载地图.我已经集成了turbolinks以使应用程序更加一致,但是现在我遇到了一个问题,我必须刷新页面以显示地图的地图.我得到的只是一个空白的地图框架.刷新页面时,地图会正确显示.

我尝试添加gem'jquery-turbolinks',但问题仍然存在.

在视图中:

<%= gmaps("map_options" => {:container_class => "map_container_renamed", "zoom" => 15, "auto_zoom" => false},"markers" => { "data" => @json }) %>
Run Code Online (Sandbox Code Playgroud)

在application.js中

//= require jquery
//= require turbolinks
//= require jquery.turbolinks
//= require jquery_ujs
//= require twitter/bootstrap
//= require_tree .
Run Code Online (Sandbox Code Playgroud)

其中,地图是空白页面源代码的要点在这里.

Sha*_*aun 24

修复程序最终我需要一个完整的页面加载脚本来刷新.

添加

'data-no-turbolink' => true
Run Code Online (Sandbox Code Playgroud)

到地图页面的链接工作.

例如,如果我有一个客户端的索引页面,并且我有一个客户端在显示页面上的位置的地图,那么转到显示页面的链接将格式如下:

<%= link_to 'View Client', client, class: "btn", 'data-no-turbolink' => true %>
Run Code Online (Sandbox Code Playgroud)

这将导致html和javascript的完全刷新,而不仅仅是更改的html.


fie*_*edl 17

技术背景

数据没有的TurboLink

请注意,只需将属性添加data-no-turbolink="true"到链接即可抑制该链接的turbolink.单击该链接会加载整个页面,而不是使用turbolinks替换内容.

但有几种方法可以使用带有gmaps4rails的turbolinks而不会抑制turbolinks.

Turbolinks回调

使用turbolinks获得一些东西的关键是使用提供的回调.在这种情况下,必须告诉gmaps4rails在turbolinks加载新页面时执行地图加载.

通常,可以使用$(document).on('page:load', function ... )例如Railscast#390中所示的.

JavaScript的同源策略

gmap4rails gem包含的google api脚本从google静态服务器请求另一个脚本.但是如果通过turbolink动态包含api,则单一来源策略会阻止对google静态服务器的请求.

单一来源政策本身是一件有用的事情.虽然有几种方法可以绕过它,但这似乎并不是一件很自然的事情.相反,执行此操作的"正确方法"是"证明"网页确实要执行远程脚本(google api),并且恶意脚本不会请求远程脚本.这是通过在html树中包含直接请求google api的脚本标记来完成的.

直接在html树中包含google api脚本标记只能在第一次请求时使用turbolinks,因为所有后来的更改都会通过turbolinks动态注入到树中.这意味着,当使用turbolinks时,即使在没有显示地图的页面上也必须包含google api.

解决方案1(推荐):使用fork for gmaps4rails

我已经提出了拉取请求,希望增加Turbolinks对gmaps4rails的支持.

演示

如果您愿意,请先查看此演示,其中显示了使用带有turbolinks的gmaps4rails:

如何在您的项目中使用它

您可以尝试这一点,并通过将fork添加到您的Gemfile来检查它是否适用于您的项目:

# Gemfile
# ...
gem 'turbolinks'
gem 'gmaps4rails', '~> 2.0.1', git: 'https://github.com/fiedl/Google-Maps-for-Rails.git'
# ...
Run Code Online (Sandbox Code Playgroud)

此外,您需要修改布局文件以在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>
Run Code Online (Sandbox Code Playgroud)

如果出于某种原因,你不想使用这个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文件:

  1. 加载谷歌地图api本身.
  2. 加载由api加载的静态文件.

您可以通过在浏览器中打开api脚本并从getScript底部的调用中复制URL来查找静态文件的URL .

但是:这样做会将静态api请求修复到您的语言环境,如果您的应用程序在国际上使用,这可能不是一件好事.


lfe*_*445 5

我无法在重新访问已经由turbolinks管理的页面时填充地图画布,尤其是在使用后退按钮时.我通过为turbolinks事件添加一个侦听器page:load来映射初始化来修复此问题.

map.js.coffee

google.maps.event.addDomListener(window, 'load', @_setup)
google.maps.event.addDomListener(window, 'page:load', @_setup)
Run Code Online (Sandbox Code Playgroud)

application.js.coffee

//= require jquery
//= require jquery.turbolinks
Run Code Online (Sandbox Code Playgroud)