1

在处理了一些代码后,我试图给一个全局变量一个值。它没有按计划工作。

我所做的是在两个文本框中输入地址和城市。它进入最后一个函数并调用获取地址坐标的 codeAddress。

从那里我将坐标发送到 setLatLng,它工作正常。但我不能使用 getLatLng 调用 longlats 来查看设定值。

如果我添加地址和城市两次,它只会显示一个值。我认为 longlats 的初始化太晚了,以至于我没有及时看到正确的值。

有什么建议吗?

相关代码如下。

<script>
var longlats ="";

function setLatLng(x,y){
    longlats = x+","+y;
    alert(longlats) //shows value
}

function getLatLng(){
    alert(longlats);
    return longlats;
    //calling this gives undefined
}

function codeAddress() {

$('#map').show();
var geocoder = new google.maps.Geocoder();
var address = document.getElementById("address").value +"," + document.getElementById("city").value;

geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
    var lat = results[0].geometry.location.lat();
    var lng = results[0].geometry.location.lng();
    locationsall[counter] = new Array();
    locationsall[counter][0] = address;
    locationsall[counter][1] = lat; //has value
    locationsall[counter][2] = lng; //has value
    setLatLng(locationsall[counter][1],locationsall[counter][2]);

counter++;

} 

$(function() {
$("#locationadd").click(function() {
   codeAddress();
   var get = getLatLng();//value is undefined..
  //i want to do stuff with the values in longlats
}
)};

</script>

编辑1

 $("#locationadd").click(function() {
var address = $("#address").val();
var city = $("#city").val();

if (address =="" || city =="") {
    $("#locationtext").text('*Please enter an address and city');
    return false;
} 
else {
    codeAddress(function(){
    var get = getLatLng();
    var longlat = get.split(",");
    var lat = longlat[0];
    var lng = longlat[1];

    var $tr2 = $('<tr>').css({
            'padding': '4px',
            'background-color': '#ddd'
    }).appendTo('#locationDeals');

    var location = [
            address,
            city
    ];
    locations.push(location);

    for (i = 0; i < 2; i++) {
        var $td2 = $('<td>').appendTo($tr2);
        $('<span>').text(location[i]).appendTo($td2);
        $('<input type="hidden">').attr({
            'name': 'loc[' + ctr + '][' + i + ']',
            'value': location[i]
        }).appendTo($td2);
    }
    var $tdRemoveRow2 = $('<td>').appendTo($tr2);
    $('<a>').attr({
        'href': '#',
        'id': 'submit-button'
    }).text("Remove").click(function() {
    var index2 = $tr2.index();
    $("#locationDeals input[type='hidden']").each(function() {
        this.name = this.name.replace(/\[(\d+)\]/, function(str2, number2) {
          return "[" + (+number2 > index2 - 1 ? number2 - 1 : number2) + "]";
        });
    });

    $tr2.remove();
    var tmp = locations.splice(locations.indexOf(location), 1);
    deleteMarker(tmp);
    return false;
    }).appendTo($tdRemoveRow2);

    ctr++;
    document.getElementById("address").value = "";
    document.getElementById("city").value = "";
    document.getElementById("address").focus();
    $("#locationtext").text('');

    return false;
    });
    } 
});
4

3 回答 3

3

问题geocoder.geocode是异步的。你不能这样做,因为你的codeAddress函数会在longlats设置之前返回。只有在谷歌地图返回结果后,您才需要更改编码样式以使用 longlats。

您需要从此更改您的代码:

$("#locationadd").click(function() {
   codeAddress();
   var get = getLatLng();//value is undefined..
  //i want to do stuff with the values in longlats
}

对此:

$("#locationadd").click(function() {
   codeAddress(function(){
     var get = getLatLng();
     //do stuff with the values in longlats
   });
});

为此,您需要更改copyAddress为:

function codeAddress(callback) {

  /*
   * Some stuff
   */

  geocoder.geocode( { 'address': address}, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      /*
       * Some stuff
       */

      setLatLng(locationsall[counter][1],locationsall[counter][2]);

      callback(); // This is where/when the values are returned
                  // so this is where/when we want to execute code.  
    } 
  })
}

补充说明:

从您的评论来看,您似乎仍在尝试这样做:

var val;
codeAddress(function(){
    val = getLatLng();
});
doStuffWith(val);

这不起作用,因为 codeAddress 在 getLatLng 执行之前返回。你需要改变你的编码风格。你需要这样写:

codeAddress(function(){
    val = getLatLng();
    doStuffWith(val);
});

也就是说,您需要将在调用 codeAddress 之后编写的所有代码移动到函数 INSIDE codeAddress中。

原因是代码执行的方式是这样的:

  • 浏览器进入 JAVASCRIPT 阶段:

       codeAddress is called
              |
              |
              |--------------> inside codeAddress a request to google maps
              |                is made which registers a callback function
              |                to be executed once it returns.
              v
       codeAddress returns
       note that at this point getLatLng isn't called yet
       this is because the browser haven't made the request
       to google maps yet because it's still executing the
       javascript engine.
              |
              v
       code written after codeAddress is executed
       (remember, the call to google maps still haven't happened yet)
              |
              v
       no more javascript to execute
    
  • javascript 阶段结束,浏览器进入 DOM 渲染阶段

       The DOM gets updated and drawn on screen if there are any changes.
    
  • DOM 渲染结束,浏览器进入网络阶段

       (note: in reality the network layer is asynchronous)
    
       Browser executes pending requests (images, iframes, XMLHttprequest etc.)
       Makes the necessary network connections and begins downloading stuff.
              |
              |
              v
       Browser services completed requests and schedules appropriate events
       (update DOM, trigger onreadystatechange etc.)
       Note that at this point no javascript or DOM updates actually happens.
       The browser does things in a loop, not recursively.
       It is at this point that the google maps request is made.
              |
              v
       No more network operations to service
    
  • 网络阶段结束,浏览器进入 JAVASCRIPT 阶段

       google maps request completes, onreadystatechange executes
              |
              |
              |----> inside onreadystatechange the callback to the
              |      google maps API is called
              |             |
              |             '-----> inside the google maps callback getLatLng
              |                     is called, then the callback to codeAddress
              |                     is called.
              |                          |
              |                          '------> inside the callback to
              |                                   codeAddress you can now
              |                                   use the returned values.
              |                                   This is the reason you need
              |                                   to move all your code here.
              v
       no more javascript to execute
    
  • javascript 阶段结束,浏览器进入 DOM 渲染阶段

并且事件循环继续。

如您所见,您不能简单地从 codeAddress 返回值。相反,您需要将代码移动到 codeAddress 中以使其在正确的时间执行。

于 2012-11-09T02:26:46.490 回答
0

你得到undefined是因为调用时getLatLng()的值longlats尚未设置。

您的函数codeAddress()发出异步请求,因此您需要使其能够接受回调作为参数。

codeAddress(function(longLat){
    // do something with longLat
}); 

声明函数 codeAddress 时,请确保执行回调并将 longLat 值传递给它。

检查这个其他答案

于 2012-11-09T02:19:39.860 回答
0

Google 地理编码服务进行异步 AJAX 调用。当您调用codeAddess()它时,它会触发 AJAX 请求并立即返回。尚未收到响应,因此尚未设置您的变量,但getLatLng()无论如何您都尝试获取它,这会显示一个空的警报框(我想)。您要做的是将回调传递给地理编码函数并在那里进行后续工作。例如,

function codeAddress(fn) {
   /* Code here */
   if (status == google.maps.GeocoderStatus.OK){
     /* More code here */
     /* Call callback in the end or after setting*/
     fn();
  }
}

你可以这样设置:

$("#locationadd").click(function() {
   codeAddress(getLatLng);
});
于 2012-11-09T02:21:14.027 回答