简体   繁体   English

Google Maps API-所有标记共享相同的信息窗口

[英]Google Maps API - All markers share the same infowindow

I have been trying to figure this out now for a while, but cant seem to get it done! 我已经尝试了一段时间,但似乎无法完成! I'm getting data from a database in Laravel via Ajax and then are trying to get the markers to show infowindows for every marker. 我正在通过Ajax从Laravel中的数据库获取数据,然后尝试获取标记以显示每个标记的信息窗口。 The markers place themself on the different addresses where I want them but they all share the same infowindow. 这些标记将它们放置在我想要它们的不同地址上,但是它们都共享相同的信息窗口。 (which is information from the last row in the database). (这是来自数据库最后一行的信息)。

I tried to implement this solution in my code: Google Maps API v3 - Markers All Share The Same InfoWindow 我尝试在代码中实现此解决方案: Google Maps API v3-标记全部共享相同的InfoWindow

But it didnt work... 但这没用...

My code looks like this: 我的代码如下所示:

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
      });
    }

  }

});

Anyone have an idea or an example on how to fix this? 任何人都有解决此问题的想法或示例吗? It's driving me nuts! 真让我发疯! :-( :-(

This is the json that is returned from the data-object: 这是从数据对象返回的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"}]

First of all let's start with mocking the provided data for this purpose i will overwrite $.getJSON 首先让我们从模拟提供的数据开始,为此我将覆盖$ .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"}]
    );
  }
};

Then let's create a small index.html to see results also include the used frameworks from their CDN urls 然后让我们创建一个小的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>

It would have been awesome to have that provided in the question :-) 在问题中提供它会很棒:-)

The main issue with the initial code is, that the method geocoder.geocode is an asyncronous operation while the bindInfoWindow function was called within the status code OK condition, which is most likely executed far after the for loop already finished. 初始代码的主要问题是,在状态代码OK条件内调用bindInfoWindow函数时,geocoder.geocode方法是一个异步操作,很可能在for循环完成之后很久才执行该方法。 That means all the arguments passed to the function is just data from the last iteration of the for loop. 这意味着传递给函数的所有参数仅是来自for循环最后一次迭代的数据。

To proof that asumption just put geocoder.geocode({'address': address}, function(results, status) { console.log("outside"); if (status === google.maps.GeocoderStatus.OK) { console.log("inside"); } }); 为了证明这一假设,只需将geocoder.geocode({'address':address},function(results,status){console.log(“ outside”); if(status === google.maps.GeocoderStatus.OK){ .log(“ inside”);}}); into your code you will see outside being triggered twice before the inside is triggered. 到您的代码中,您将看到内部触发之前,外部触发了两次。 The inside is delayed because there are some requests to google to fullify before it is executed. 内部执行延迟是因为有一些要求Google执行之前要完成的请求。

To make a quick fix just gather all the data in the first loop and add them utilizing a recursive function. 要进行快速修复,只需在第一个循环中收集所有数据,然后使用递归函数将其添加即可。

The full code looks like this (i wrapped the whole block into the default maps callback) 完整的代码如下所示(我将整个代码块包装到默认的maps回调中)

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
        });
      }

    }

  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM