【问题标题】:Set unique infoWindow content on click for each of several unique markers using Google Maps使用谷歌地图为几个独特的标记中的每一个设置独特的 infoWindow 内容
【发布时间】:2016-03-02 15:53:13
【问题描述】:

我使用 Ruby on Rails 构建了一个公共汽车跟踪应用程序,它在一张地图上显示用户的位置以及附近几辆公共汽车的位置。每条总线都有自己的标记,带有一个事件监听器,点击时会打开一个信息窗口。

我希望每个信息窗口根据它所连接的总线的参数显示一个唯一的描述符。我通过总线数组displayBuses 中的每个元素循环创建每个标记,并在描述符数组busInfo 中分配相应的元素。

我在 Stack Overflow 上找到了几篇文章,这些文章模拟了我正在尝试做的事情,有些是通过创建多个 infoWindows 而有些是通过创建一个 infoWindow 并使用 Google 地图的 setContent 函数进行更新描述符。

刚开始时,我试图为每条总线创建一个新的标记、描述符和信息窗口,但没有得到任何信息窗口。接下来我尝试创建一个窗口并使用setContent 每次更新它,但我有busInfo 作为每次更新的字符串;我在信息窗口中获取内容,但每辆公共汽车都是一样的。我将busInfos 更改为一个数组,以便为​​每条总线存储不同的字符串。现在 我的代码正在正确创建信息窗口,但它没有显示描述符(每个窗口都弹出空)。

以下是相关代码:

var infoWindow = new google.maps.InfoWindow;

var busLatLng, busMarker, i;

var busInfos = [];

for (i = 0; i < displayBuses.length; i++) {  
    var busLat = displayBuses[i].LATITUDE;
    var busLng = displayBuses[i].LONGITUDE;
    var busNum = displayBuses[i].VEHICLE;
    var busRoute = displayBuses[i].ROUTE;
    var busStop = displayBuses[i].TIMEPOINT;

    busLatLng = new google.maps.LatLng(busLat, busLng);

    busMarker = new google.maps.Marker({
        position: busLatLng,
        map: map,
        title: 'Bus number ' + busNum,
        icon: busIcon,
        animation: google.maps.Animation.BOUNCE
    });

    busInfos[i] = new google.maps.InfoWindow({
            content: 'Bus number ' + busNum + ' is on Route ' + busRoute + '. The next stop is at ' + busStop + '.'
    });

    google.maps.event.addListener(busMarker, 'click', (function(busMarker) {
         return function() {
             infoWindow.setContent(busInfo[i]);
             infoWindow.open(map, busMarker);
         }
    })(busMarker));
}

这是完整的 locations.js.erb 文件:

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require bootstrap-sprockets
//= require_tree .

$(document).ready(function() {
	var currentLat = gon.current_lat;
	var currentLng = gon.current_lng;
	var displayBuses = gon.display_buses;

	var currentLatLng = new google.maps.LatLng(currentLat, currentLng);

	function initMap() {
		var map = new google.maps.Map(document.getElementById('map'), {
			center: currentLatLng,
			zoom: 15,
			scrollwheel: false
		});

		setMarkers(map);
	}

	function setMarkers(map) {
		var userMarker = new google.maps.Marker({
			position: currentLatLng,
			map: map,
			title: 'User',
			animation: google.maps.Animation.DROP
		});

		var userInfo = new google.maps.InfoWindow({
			content: 'You are here.'
		});

		google.maps.event.addListener(userMarker, 'click', function() {
			userInfo.open(map, userMarker);
		});

		var imgHt = 30;
		var imgWd = imgHt*1.5;

		var busIcon = {
    	url: "<%= asset_path 'bus-marker.png' %>",
      scaledSize: new google.maps.Size(imgHt, imgWd),
      origin: new google.maps.Point(0, 0),
      anchor: new google.maps.Point(imgWd/2, imgHt)
    };

		var infoWindow = new google.maps.InfoWindow;

		var busLatLng, busMarker, i;

		var busInfos = [];

		for (i = 0; i < displayBuses.length; i++) {  
	    var busLat = displayBuses[i].LATITUDE;
			var busLng = displayBuses[i].LONGITUDE;
			var busNum = displayBuses[i].VEHICLE;
			var busRoute = displayBuses[i].ROUTE;
			var busStop = displayBuses[i].TIMEPOINT;

	    busLatLng = new google.maps.LatLng(busLat, busLng);

	    busMarker = new google.maps.Marker({
      	position: busLatLng,
				map: map,
				title: 'Bus number ' + busNum,
				icon: busIcon,
				animation: google.maps.Animation.BOUNCE
	    });

	    busInfos[i] = new google.maps.InfoWindow({
				content: 'Bus number ' + busNum + ' is on Route ' + busRoute + '. The next stop is at ' + busStop + '.'
			});

	    google.maps.event.addListener(busMarker, 'click', (function(busMarker) {
	         return function() {
	             infoWindow.setContent(busInfo[i]);
	             infoWindow.open(map, busMarker);
	         }
	    })(busMarker));
		}
	};

	google.maps.event.addDomListener(window, 'load', initMap);
});

我正在使用 gem gon 从控制器中提取 ruby​​ 变量,但在修改了 JS 控制台后,我确信这些变量正确输入。我只是不明白为什么将busInfos 更改为数组会导致它无法正确显示。任何帮助表示赞赏。

【问题讨论】:

  • 注意到您是如何传递busMarker 来创建回调函数的,同时传递busInfo[i]
  • 这对我来说很有意义,但现在我收到一条错误消息:Uncaught SyntaxError: Unexpected token [猜测这是一个简单的语法错误,但最终......
  • 希望你没有使用busInfo[i]作为参数名
  • 是的,希望对吧?

标签: javascript ruby-on-rails ruby google-maps google-maps-api-3


【解决方案1】:

@Musa,你说得对,我也需要通过busInfo[i]。我花了一分钟才弄清楚哪个函数正在发送参数,哪个函数正在接收它们,但现在我将其设置如下:

busInfo[i] = new google.maps.InfoWindow({
  content: 'Bus number ' + busNum + ' is on Route ' + busRoute + '. The next stop is at ' + busStop + '.'
});

google.maps.event.addListener(busMarker, 'click', (function(busMarker, busInfo) {
  return function() {
    infoWindow.setContent(busInfo.content);
    infoWindow.open(map, busMarker);
  }
})(busMarker, busInfo[i]));

另一个问题是我使用.setContent 将对象busInfo 添加到窗口中,而不是其字符串属性.content。现在窗口可以正确显示了。

感谢您的帮助!

【讨论】:

    猜你喜欢
    • 2011-08-23
    • 1970-01-01
    • 2011-08-17
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 2016-11-27
    相关资源
    最近更新 更多