我一直试图解决这个问题,但似乎无法完成它!我通过Ajax从Laravel的数据库中获取数据,然后尝试获取标记以显示每个标记的信息。标记将它们放在我想要它们的不同地址上,但它们都共享相同的信息窗口。 (这是数据库中最后一行的信息)。
我尝试在我的代码中实现此解决方案:Google Maps API v3 - Markers All Share The Same InfoWindow
但它没有用......
我的代码如下所示:
var app = new Vue({
el: 'body',
data: {
users: $.getJSON("http://localhost:8000/data", function(data){
var map = new google.maps.Map(document.querySelector('#map'), {
center: {lat: 57.708870, lng: 11.974560 },
zoom: 14
});
var geocoder = new google.maps.Geocoder();
function bindInfoWindow(marker, map, infowindow, html) {
marker.addListener('click', function() {
infowindow.setContent(html);
infowindow.open(map, this);
});
}
for (var i = 0; i < data.length; i++) {
var address = data[i]['address'] + ' Göteborg';
var contentString = '<h4 style="color: #ffc62d">' + data[i]['foodtruck_name'] + '</h4>'
+ '<b>Mat:</b> ' + data[i]['type_of_food']
+ '<br><b>Öppettider:</b> '+ data[i]['open_hours']
+ '<br><b>Adress:</b> '+ data[i]['address']
+ '<br><b>Hemsida:</b> '+ '<a href="http://' + data[i]['webadress'] + '" target="_blank">' + data[i]['webadress'] + '</a>';
var image = {
url: 'http://localhost:8000/img/foodtruck.png',
// This marker is 20 pixels wide by 32 pixels high.
size: new google.maps.Size(45, 30),
// The origin for this image is (0, 0).
origin: new google.maps.Point(0, 0),
// The anchor for this image is the base of the flagpole at (0, 32).
anchor: new google.maps.Point(0, 30)
};
var shape = {
coords: [1, 1, 1, 30, 45, 20, 18, 1],
type: 'poly'
};
var infoWindow = new google.maps.InfoWindow({
maxWidth: 250
});
geocoder.geocode({'address': address}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: image,
shape: shape
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
bindInfoWindow(marker, map, infoWindow, contentString);
});
};
})
},
methods: {
createMap: function() {
var map = new google.maps.Map(document.querySelector('#map'), {
center: {lat: 57.708870, lng: 11.974560 },
zoom: 14
});
}
}
});
任何人都有关于如何解决此问题的想法或示例?它让我疯了! : - (
这是从数据对象返回的json:
[{"foodtruck_name":"Emils Foodtruck","open_hours":"11:00-16:00","address":"Stigbergsliden 9","type_of_food":"Mexikanskt tema","webadress":"www.emilwallgren.se"},{"foodtruck_name":"Kodameras Truck","open_hours":"08:00-17:00","address":"F\u00f6rsta L\u00e5nggatan 16","type_of_food":"Cookies","webadress":"www.kodamera.se"}]
答案 0 :(得分:0)
首先让我们开始模拟为此目的提供的数据,我将覆盖$ .getJSON
var $ = {
getJSON : function(url, callback){
callback(
[{"foodtruck_name":"Emils Foodtruck","open_hours":"11:00-16:00","address":"Stigbergsliden 9","type_of_food":"Mexikanskt tema","webadress":"www.emilwallgren.se"},{"foodtruck_name":"Kodameras Truck","open_hours":"08:00-17:00","address":"F\u00f6rsta L\u00e5nggatan 16","type_of_food":"Cookies","webadress":"www.kodamera.se"}]
);
}
};
然后让我们创建一个小的index.html,看看结果还包括他们的CDN网址中使用过的框架
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Maps</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
#map{
width: 100%;
height: 300px;
}
</style>
</head>
<body>
<div id = "map"></div>
<script src="//cdn.jsdelivr.net/vue/1.0.25/vue.min.js"></script>
<script src="js/main.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCTlirlFFxIHhstDEeARWQTym5AeU4db1I&callback=initMap"></script>
</body>
</html>
在问题中提供的内容真是太棒了: - )
初始代码的主要问题是,方法geocoder.geocode是异步操作,而bindInfoWindow函数是在状态代码OK条件中调用的,很可能在for循环已经完成之后执行。这意味着传递给函数的所有参数都只是for循环的最后一次迭代的数据。
证明刚刚提出的假设 geocoder.geocode({'address':address},function(results,status){ 的console.log( “外侧”); if(status === google.maps.GeocoderStatus.OK){ 的console.log( “内部”); } }); 在你的代码中,你会看到外部在触发内部之前被触发两次。内部被推迟,因为有一些请求谷歌在执行之前加强。
要快速修复,只需收集第一个循环中的所有数据,然后使用递归函数添加它们。
完整代码看起来像这样(我将整个块包装到默认的map回调中)
var $ = {
getJSON : function(url, callback){
callback(
[{"foodtruck_name":"Emils Foodtruck","open_hours":"11:00-16:00","address":"Stigbergsliden 9","type_of_food":"Mexikanskt tema","webadress":"www.emilwallgren.se"},{"foodtruck_name":"Kodameras Truck","open_hours":"08:00-17:00","address":"F\u00f6rsta L\u00e5nggatan 16","type_of_food":"Cookies","webadress":"www.kodamera.se"}]
);
}
};
initMap = function(){
var app = new Vue({
el: 'body',
data: {
users: $.getJSON("http://localhost:8000/data", function(data){
function bindInfoWindow(marker) {
marker.addListener('click', function() {
this.infowindow.setContent(this.infowindowContent)
this.infowindow.open(this.map, this);
});
}
var addmarkersRecursive = function addMarkers(markers){
if(markers.length > 0){
markerConfig = markers.shift();
geocoder.geocode({'address': markerConfig.address}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
map: markerConfig.map,
position: results[0].geometry.location,
icon: markerConfig.image,
shape: markerConfig.shape,
infowindow : markerConfig.infowindow,
infowindowContent : markerConfig.contentString
});
bindInfoWindow(marker, markerConfig.map, markerConfig.infoWindow, markerConfig.contentString);
addmarkersRecursive(markers);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
};
var map = new google.maps.Map(document.querySelector('#map'), {
center: {lat: 57.708870, lng: 11.974560 },
zoom: 14
});
var geocoder = new google.maps.Geocoder();
var markers = [];
for (var i = 0; i < data.length; i++) {
var address = data[i]['address'] + ' Göteborg';
var contentString = '<h4 style="color: #ffc62d">' + data[i]['foodtruck_name'] + '</h4>'
+ '<b>Mat:</b> ' + data[i]['type_of_food']
+ '<br><b>Öppettider:</b> '+ data[i]['open_hours']
+ '<br><b>Adress:</b> '+ data[i]['address']
+ '<br><b>Hemsida:</b> '+ '<a href="http://' + data[i]['webadress'] + '" target="_blank">' + data[i]['webadress'] + '</a>';
var image = {
url: 'http://t1.gstatic.com/images?q=tbn:ANd9GcT_vg5Yh1dmbqL4cVfaBoZhFfPwXJIZhJ5MFU9Y6lm4173JsKb8XEFK',
// This marker is 20 pixels wide by 32 pixels high.
size: new google.maps.Size(45, 30),
// The origin for this image is (0, 0).
origin: new google.maps.Point(0, 0),
// The anchor for this image is the base of the flagpole at (0, 32).
anchor: new google.maps.Point(0, 30)
};
markers.push({
map : map,
address: address,
contentString: contentString,
image: image,
shape : {
coords: [1, 1, 1, 30, 45, 20, 18, 1],
type: 'poly'
},
infowindow : new google.maps.InfoWindow({maxWidth: 250 })
})
};
addmarkersRecursive(markers);
})
},
methods: {
createMap: function() {
var map = new google.maps.Map(document.querySelector('#map'), {
center: {lat: 57.708870, lng: 11.974560 },
zoom: 14
});
}
}
});
}