Google Maps V3中的循环地理编码和标记

4
我有一些代码问题,我在SQL数据库中有一个机场列表,并且我想为每个机场创建标记。
对于地址,我获得了每个机场的ICAO代码,ICAO对于每个机场都是唯一的。
我将数据作为数组从数据库中获取。
它保存在“temp”中,使用分隔函数和for循环逐个获取它们。
地理编码不是问题,但我不知道为什么对于标题和单击事件,总是使用数组中的最后一个。
这是页面,在数据库中的最后一个条目是ZBAA。
所有标记都放置在正确的位置,但标题是错误的:s

http://mizar.lte.lu/~pr1011_meteo/projet/cartemonde4.php

问题可能出在"address",但我不确定。
for (var i = 0; i < temp.length; ++i){

     var address=temp[i];

     geocoder.geocode({ 'address': address}, function(results){            
          var marker  = new google.maps.Marker({
              map: map, 
              position: results[0].geometry.location,
              title:address
          });

          google.maps.event.addListener(marker, 'click', function() {
               window.open ('infomonde.php?icao='+address+'&language=fr', 'Informations météo', config='height=400, width=850, toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, directories=no, status=no')});
     });  
};

address=temp[i] 传递的 i 有关,似乎需要做一个闭包并传入 address,但如果没有放置 jsfiddle 演示,我无法确定。 - KJYe.Name
你介意为地址/临时数组提供一些虚拟字段吗? - KJYe.Name
闭包是什么意思?你所说的虚拟字段是什么意思?如果你的意思是输入一些错误的条目,我已经尝试过了,地理编码失败了^^ - user657848
@user657848,请查看我的示例并探索演示。如果您有任何问题,请告诉我,并随意发表评论。 - KJYe.Name
2个回答

10
这里有一个JSFiddle演示,使用“虚拟”地址和警报来显示与每个标记相关的正确数据:
你所面临的是循环内典型的闭包/作用域问题。为了解决这个问题,在传递到geocode和其中的回调函数之前,使用闭包将temp[i]变量本地化:
    for (var i = 0; i < temp.length; ++i) {
        (function(address) {
            geocoder.geocode({
                'address': address
            }, function(results) {
                var marker = new google.maps.Marker({
                    map: map,
                    position: results[0].geometry.location,
                    title: address
                });

                google.maps.event.addListener(marker, 'click', function() {
                    //alert(address);  //use alert to debug address
                    window.open('infomonde.php?icao=' + address + '&language=fr', 'Informations météo', config = 'height=400, width=850, toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, directories=no, status=no')
                });
            });
        })(temp[i]);  //closure passing in temp[i] and use address within the closure
    }

0

我猜是因为

geocoder.geocode({ 'address': address}, function(results){ ... });

回调在相同的上下文中执行。

尝试在相同的上下文中执行标记。下面的代码将等待所有地理编码器获取完毕,然后解析为标记。

var results = {};
var waiting = temp.length;

while(temp.length > 0){

  var fetching = temp.pop();

  geocoder.geocode(
    { address: fetching}, 
    function(response){
      results[fetching] = response[0].geometry.location;
      --waiting;
      if(waiting == 0) // wait for everything to finish
        setMarker();
    }
  );
}
var setMarker = function(){
  for(var element in results){
    var marker  = new google.maps.Marker({
              map: map, 
              position: results[element],
              title: element
              });

    google.maps.event.addListener(marker, 'click', function() {
    window.open ('infomonde.php?icao='+element+'&language=fr', '', 'configs')});
  }
}

如果我没记错的话,ps window.open是用来打开弹出窗口的。但是有些浏览器会拒绝弹出窗口的标题(可能导致无法打开弹出窗口)。所以我通常会将标题留空。


所以我应该保留address=temp[i]吗?因为你在你的geocode中使用了它。 - user657848
{ address: address} 改为 { address: fetching } 是我的错误。 - Bonshington

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接