ruby-on-rails – Google Maps for Rails – 使用AJAX更新标记

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – Google Maps for Rails – 使用AJAX更新标记前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在开发一个Web应用程序,我使用Ruby on Rails.我们的索引由地图和搜索字段组成.您可以搜索位置,地图会更新其标记.

我想使用Ajax来避免刷新页面.所以我添加了remote:true表单,控制器中的respond_to和新的search.js.erb.我的search.js.erb呈现了部分_googlemap.erb,其中包含初始化地图的脚本.

这是我的问题.由于地图已经存在,就好像我想要创建两次相同的对象,这当然不起作用并且非常糟糕.我想用新的标记更新地图中的标记.但我找不到办法做到这一点.

我看到之前版本的Gmaps4rails集成了一种方法(Gmaps.map.replaceMarkers(your_markers_json_array);)但它现在似乎不起作用.当我使用它时,我收到此错误:“TypeError:Gmaps.map未定义”.我试过“handler.replaceMarkers();”但这次我有“TypeError:handler.replaceMarkers不是函数”.

我是Javascript和Rails的新手,但我想提高自己的知识,我真的需要继续使用这个Web应用程序的其余部分.我一直在网上寻找解决方案但是徒劳无功.

Live website here

请问,有人可以告诉我我该怎么做以及我做错了什么?

提前谢谢了,

席琳

zones_controller.rb

  1. def search
  2. respond_to do |format|
  3. format.html.none do
  4. search_params = params[:zone][:search]
  5. coordinates = Geocoder.coordinates(search_params).join(",")
  6. @zones = Zone.search(
  7. "",{ "aroundLatLng" => coordinates,"aroundRadius" => 500000 #Searches around 500 km
  8. })
  9. if coordinates.nil?
  10. @zones = Zone.search(params[:search])
  11. elsif @zones.empty?
  12. @zones = Zone.all
  13. flash[:error] = "No zone could be found. Please try again."
  14. end
  15. build_map(@zones)
  16. end
  17.  
  18. format.js
  19. end
  20. end
  21.  
  22. def build_map(array)
  23. @hash = Gmaps4rails.build_markers(array) do |zone,marker|
  24. marker.lat zone.latitude
  25. marker.lng zone.longitude
  26. marker.json({ title: zone.description,id: zone.id })
  27. marker.infowindow render_to_string(:partial => "/zones/map_Box",locals: { zone: zone })
  28. end
  29. end

search.html.erb

  1. <div id="map" style='width: 100%; height: 700px;'>
  2. </div>
  3. <!-- Beginning Google maps -->
  4.  
  5. <script type="text/javascript" id="map_script">
  6. $(document).ready(function() {
  7. <%= render 'googlemap',hash: @hash %>
  8. }); // Document ready
  9. </script>

_googlemap.erb

  1. handler = Gmaps.build('Google');
  2. handler.buildMap({ provider: {
  3. disableDefaultUI: true,mapTypeId: google.maps.MapTypeId.TERRAIN
  4. },internal: {id: 'map'}
  5. },function(){
  6. markers_json = <%= raw hash.to_json %>;
  7. markers = _.map(markers_json,function(marker_json){
  8.  
  9. marker = handler.addMarker(marker_json);
  10. handler.getMap().setZoom(4);
  11.  
  12. _.extend(marker,marker_json);
  13.  
  14. marker.infowindow = new google.maps.InfoWindow({
  15. content: marker.infowindow
  16. });
  17.  
  18. return marker;
  19. });
  20.  
  21. handler.bounds.extendWith(markers);
  22. handler.fitMapToBounds();
  23. });

search.js.erb

  1. $('#map_script').replaceWith("<%= render 'googlemap',hash: @hash %>");

解决方法

为什么不用新标记更新地图?这意味着,不是在每次搜索后重新渲染整个地图,只需通过删除所有标记添加标记来更新现有地图上的标记.

我没有验证该方法,但我想它应该工作并且更有效:

创建app / assets / javascript / map.js文件.您可以在那里存储与地图相关的功能.创建一个函数来更新此文件中的地图标记

map.js

  1. (function() {
  2. /* __markers will hold a reference to all markers currently shown
  3. on the map,as GMaps4Rails won't do it for you.
  4. This won't pollute the global window object because we're nested
  5. in a "self-executed" anonymous function */
  6. var __markers;
  7.  
  8. function updateMarkers(map,markersData)
  9. {
  10. // Remove current markers
  11. map.removeMarkers(__markers);
  12.  
  13. // Add each marker to the map according to received data
  14. __markers = _.map(markersData,function(markerJSON) {
  15. marker = map.addMarker(markerJSON);
  16. map.getMap().setZoom(4); // Not sure this should be in this iterator!
  17.  
  18. _.extend(marker,markerJSON);
  19.  
  20. marker.infowindow = new google.maps.InfoWindow({
  21. content: marker.infowindow
  22. });
  23.  
  24. return marker;
  25. });
  26.  
  27. map.bounds.extendWith(__markers);
  28. map.fitMapToBounds();
  29. };
  30.  
  31. // "Publish" our method on window. You should probably have your own namespace
  32. window.updateMarkers = updateMarkers;
  33. })();

功能可用于初始化地图并进行更新.由于您不会(如果我的回答满足您)将地图渲染两次,您可以删除_google_map.erb并将其内容放回search.html.erb,但使用我们刚刚创建的函数

search.html.erb

  1. <div id="map" style='width: 100%; height: 700px;'>
  2. </div>
  3. <!-- Beginning Google maps -->
  4.  
  5. <script type="text/javascript" id="map_script">
  6. $(document).ready(function() {
  7. mapHandler = Gmaps.build('Google');
  8. mapHandler.buildMap({ provider: {
  9. disableDefaultUI: true,mapTypeId: google.maps.MapTypeId.TERRAIN
  10. },internal: {id: 'map'}
  11. },function(){
  12. var markersData = <%= raw @hash.to_json %>;
  13. updateMarkers(mapHandler,markersData);
  14. });
  15. }); // Document ready
  16. </script>

在声明变量时请不要忘记var关键字,否则它们最终会成为全局变量,而这很糟糕^^
请注意,我故意将mapHandler作为全局变量:当有人使用搜索时,您需要访问处理程序以更新标记.这可能不是一个理想的事情,但这个问题不是重构你的代码所以让我们保持这种方式.

所以现在我的解决方案为您提供了一个在页面加载时使用给定标记初始化的地图.换句话说,一切都没有改变!

但是,您现在可以重复使用此updateMarkers函数来更改地图上显示标记.这就是你search.js.erb脚本应该做的事情:

search.js.erb

  1. (function() {
  2. var markersData = <%= raw @hash.to_json %>;
  3. updateMarkers(mapHandler,markersData);
  4. })();

而已!希望它能带你进入你项目的下一步:)

猜你在找的Ruby相关文章