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

时间:2016-06-19 14:46:39

标签: javascript jquery laravel google-maps-api-3 vue.js

我一直试图解决这个问题,但似乎无法完成它!我通过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"}]

1 个答案:

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

    }

  });
}