12

gmaps4railsを使用して、「クライアント」の表示ページに地図をロードしています。ターボリンクを統合してアプリをより高速にしましたが、地図を表示するために地図でページを更新する必要があるという問題が発生しています。私が得るのは白地図のフレームだけです。ページを更新すると、マップが正しく表示されます。

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 .

ここで地図が空白になっているページソースの要点。

4

6 に答える 6

24

スクリプトを更新するには、ページ全体を読み込む必要があるという修正が行われました。

追加する

'data-no-turbolink' => true

マップページへのリンクが機能しました。

たとえば、クライアントのインデックス ページがあり、ショー ページにクライアントが住んでいる場所の地図がある場合、ショー ページに移動するためのリンクは次のようにフォーマットされます。

<%= link_to 'View Client', client, class: "btn", 'data-no-turbolink' => true %>

これにより、変更された html だけでなく、html と JavaScript が完全に更新されます。

于 2012-12-11T17:22:40.233 に答える
17

技術的背景

データなしターボリンク

data-no-turbolink="true"リンクに属性を追加するだけで、そのリンクのターボリンクが抑制されることに注意してください。そのリンクをクリックすると、コンテンツがターボリンクに置き換えられるのではなく、ページ全体が読み込まれます。

しかし、ターボリンクを抑制せずに gmaps4rails でターボリンクを使用する方法はいくつかあります。

ターボリンクのコールバック

ターボリンクで何かを動作させるための鍵は、提供されたコールバックを使用することです。この場合、ターボリンクが新しいページをロードしたときにマップのロードを実行するように gmaps4rails に指示する必要があります。

一般に、Railscast #390$(document).on('page:load', function ... )に示されているように使用できます。

JavaScript の同一生成元ポリシー

gmap4rails gem に含まれるGoogle API スクリプトは、Google 静的サーバーから別のスクリプトを要求します。ただし、API がターボリンクによって動的に含まれている場合、シングルオリジン ポリシーにより、Google 静的サーバーへのリクエストが防止されます。

シングルオリジン ポリシー自体は便利なものです。これを回避する方法はいくつかありますが、これは自然なことではないようです。代わりに、それを行うための「正しい方法」は、Web ページが本当にリモート スクリプト (Google API) を実行しようとしていること、およびリモート スクリプトが悪意のあるスクリプトによって要求されていないことを「証明」することです。これは、Google API を直接リクエストする script タグを html ツリーに含めることによって行われます。

html ツリーに直接 google api スクリプト タグを含めることができるのは、ターボリンクを使用する場合、最初のリクエストでのみ可能です。これは、その後のすべての変更がターボリンクによってツリーに動的に注入されるためです。つまり、ターボリンクを使用する場合、地図を表示しないページでも Google API を含める必要があります。

解決策 1 (推奨): gmaps4rails に fork を使用する

うまくいけば、gmaps4rails の Turbolinks サポートを追加して、プルリクエストを作成しました。

デモ

必要に応じて、ターボリンクで gmaps4rails を使用する方法を示すこのデモを最初に見てください。

プロジェクトでこれを使用する方法

これを試して、フォークを 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 を使用する 2 つの代替方法があります。

解決策 2: 手動で行う

基本的に fork と同じことを行い (解決策 1)、レイアウト ファイルのヘッドに API スクリプトを手動で追加できます。次に、ターボリンクを介してページをロードするときに、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

次の 2 つのことを行う JavaScript ファイルを追加する必要があります。

  1. Google マップ API自体を読み込みます。
  2. API によってロードされる静的ファイルをロードします。

ブラウザーでAPI スクリプトgetScriptを開き、下部の呼び出しから URL をコピーすると、静的ファイルへの URL を見つけることができます。

しかし: これを行うと、静的 API 要求がロケールに修正されます。これは、アプリが国際的に使用されている場合、おそらく良いことではありません。

于 2013-03-19T02:19:12.760 に答える
0

このGithub issueにあるように、すべてのページに Google スクリプトを含めることができます。これにより、Turbolinks が新しくナビゲートされたページに対して gmaps4rails JavaScript を実行しないという問題が修正されます。

gmaps4rails gem にはjavascript の依存関係があることに注意してください。

<script src="//maps.google.com/maps/api/js?v=3.13&amp;sensor=false&amp;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&amp;sensor=false&amp;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

アプリケーション.js

これを追加:

//= require gmaps/google

これで、ページを更新しなくても地図が読み込まれるはずです。

于 2014-10-28T06:17:49.053 に答える
0

私は同じ問題を抱えていましたが、ターボリンクをオフにしたくなかったので、ターボリンク 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 );
});
};

Google Places ライブラリも使用しているため、 init_google_api()で呼び出すことができる関数がいくつかあります。

マップが必要な各ビューに、

<%= javascript_tag do %>
   init_google_api(init_map(marker_check));
<% end %>

ビューの最後に。すべてを修正し、複数のマップが必要な場合などにコードをドライに保ちます。

私が間違っていなければ、このアプローチはターボリンクの問題を回避します。ビューが呼び出されるたびに、init_google_api 関数とパラメーターとして渡される関数が実行されるためです (これが関数式を使用する理由です)。したがって、関数が呼び出されるたびにコードが実行されます。

于 2015-03-02T10:50:41.360 に答える
0

GoogleマップのURLからコールバックを直接使用できます

<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 5を使用しています。このコードでわかるように、

$(document).on('ready turbolinks:load')

于 2016-05-03T00:56:43.483 に答える