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 is undefined ”。 我试过“ handler.replaceMarkers(); ”但这次我有“ TypeError: handler.replaceMarkers is not a function ”。

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

在这里直播网站

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

提前谢谢了,

席琳

zones_controller.rb

 def search respond_to do |format| format.html.none do search_params = params[:zone][:search] coordinates = Geocoder.coordinates(search_params).join(",") @zones = Zone.search( "", { "aroundLatLng" => coordinates, "aroundRadius" => 500000 #Searches around 500 km }) if coordinates.nil? @zones = Zone.search(params[:search]) elsif @zones.empty? @zones = Zone.all flash[:error] = "No zone could be found. Please try again." end build_map(@zones) end format.js end end def build_map(array) @hash = Gmaps4rails.build_markers(array) do |zone, marker| marker.lat zone.latitude marker.lng zone.longitude marker.json({ title: zone.description, id: zone.id }) marker.infowindow render_to_string(:partial => "/zones/map_box", locals: { zone: zone }) end end 

search.html.erb

  
$(document).ready(function() { }); // Document ready

_googlemap.erb

 handler = Gmaps.build('Google'); handler.buildMap({ provider: { disableDefaultUI: true, mapTypeId: google.maps.MapTypeId.TERRAIN }, internal: {id: 'map'} }, function(){ markers_json = ; markers = _.map(markers_json, function(marker_json){ marker = handler.addMarker(marker_json); handler.getMap().setZoom(4); _.extend(marker, marker_json); marker.infowindow = new google.maps.InfoWindow({ content: marker.infowindow }); return marker; }); handler.bounds.extendWith(markers); handler.fitMapToBounds(); }); 

search.js.erb

 $('#map_script').replaceWith(""); 

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

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

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

map.js

 (function() { /* __markers will hold a reference to all markers currently shown on the map, as GMaps4Rails won't do it for you. This won't pollute the global window object because we're nested in a "self-executed" anonymous function */ var __markers; function updateMarkers(map, markersData) { // Remove current markers map.removeMarkers(__markers); // Add each marker to the map according to received data __markers = _.map(markersData, function(markerJSON) { marker = map.addMarker(markerJSON); map.getMap().setZoom(4); // Not sure this should be in this iterator! _.extend(marker, markerJSON); marker.infowindow = new google.maps.InfoWindow({ content: marker.infowindow }); return marker; }); map.bounds.extendWith(__markers); map.fitMapToBounds(); }; // "Publish" our method on window. You should probably have your own namespace window.updateMarkers = updateMarkers; })(); 

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

search.html.erb

  

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

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

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

search.js.erb

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

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

我尝试了相同的事情,但不是更新marker你应该在partial/placeholder包含地图,然后更新它…

例如,这是显示地图的视图…我将使用最新的地图和标记更新此视图/占位符

 

在users_controller.rb中

  ##take index action or any other action def index ##do your stuff and get more users respond_to do |format| format.html format.js end end 

在index.js.erb中

 ##update the placeholder/partial with new map with new markers $("#map_users_index").html("<%= escape_javascript(render(:partial => 'index')) %>"); 

我有我自己的工作代码…… 这里