2008-11-12 130 views
1

我目前正在研究Google地圖項目並正在實施搜索功能。在我的搜索功能中,我試圖在旁邊列出哪些搜索製作者剛剛添加到地圖中的內容對應於每個大廳。然而,在組裝這個字符串時,我遇到了一個問題,如果我不先輸入數據,我的side_bar_html變量將不會輸出。Javascript範圍錯誤

這是我的searchMap函數。該變量聲明爲這樣:var side_bar_html = "";

function searchMap(term, map) { 

closeSearch(); 

searchCount = 0; 
searchMarkers = []; 

var request = GXmlHttp.create(); 

    request.open("GET", "admin/search.php?s=" + term, true); 

    request.onreadystatechange = function() { 

    if (request.readyState == 4) { 

     var xmlDoc = GXml.parse(request.responseText); 
     var points = xmlDoc.documentElement.getElementsByTagName("point"); 

     var polygonsToShow = []; 
     for (var i = 0; i < points.length; i++) {         
      var lat = parseFloat(points[i].getAttribute("lat")); 
      var lng = parseFloat(points[i].getAttribute("lng")); 
      var pid = points[i].getAttribute("id"); 
      for(var j = 0; j < polygons.length; j++) { 
       if(polygons[j].vt_bid == pid) { 
        polygonsToShow.push(j); 
       } 
      } 
      var point = new GLatLng(lat,lng);   
      var pname = points[i].getAttribute("name"); 
      var curMarker = createSearchMarker(point, pid, pname,getLetter(i));     
      map.addOverlay(curMarker); 
     } 
     //olays.buildings.checked = false; : Figure out some way to uncheck the buildings overlay checkbox? 
     for(var k = 0; k < polygons.length; k++) { 
      polygons[k].hide(); 
     } 

     for(var l = 0; l < polygonsToShow.length; l++){ 
      polygons[polygonsToShow[l]].show(); 
     } 
    } 
} 

request.send(null); 
alert(side_bar_html); //side_bar_html will be empty unless I alert the variable 


searchResults = new HtmlControl('<div style="background-color:white; border:solid 1px grey; padding:2ex; overflow:auto; width:125px; margin:1px; font-size:14px;"><img align="right" style="cursor: pointer;" src="http://www.thebort.com/maps/images/close.gif" onclick="closeSearch()"><strong>Search</strong><br/>' + side_bar_html + '</div>', {selectable:true}); 
map.addControl(searchResults, new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(20, 70))); 

} 

和函數來創建搜索標記:

function createSearchMarker(point, id, pname, letIcon) { 
    var marker = new GMarker(point,letIcon); 
    GEvent.addListener(marker, "click", function() {   
     marker.openInfoWindowHtml('<a href="#" onclick=\'tb_show("' + pname + '","admin/get_info.php?b=' + id + '&KeepThis=true&TB_iframe=true&height=400&width=600",false); return false;\'>' + pname + '</a>'); 

    }); 

side_bar_html = side_bar_html + '<a href="javascript:clickSearch(' + searchCount + ')">' + String.fromCharCode("A".charCodeAt(0) + searchCount) + ': ' + pname + '</a><br>'; 
marker.vt_id = id; 
    searchMarkers.push(marker); 
searchCount++; 

    return marker; 
} 

我想保持代碼曝光這個項目至少現在這樣如果有什麼需求闡述請讓我知道。謝謝!

回答

4

所以我對你的問題的理解是,side_bar_htmlonreadystatechange函數調用期間設置的,但你看不到它,除非你提醒它被設置。

以下是可能發生的情況:Ajax請求需要一些時間才能發生。當你打電話req.send(null)然後啓動請求,但你的onreadystatechange函數將不會被調用,直到你的Web瀏覽器發出請求並獲得響應後的某個時間。

因此,當您立即嘗試使用side_bar_html值時,它不起作用,因爲響應尚未返回。但是,當您提醒該值時,執行警報所需的時間會使瀏覽器有時間得到響應,並適當設置值side_bar_html

您的根本問題是,Ajax是異步的(這是A的來源),並且您試圖同步使用它(意味着您認爲事情總是以特定順序發生)。您最好的辦法是將side_bar_html的代碼放入您的onreadystatechange函數中,以便它在設置之前不會被使用。

0

將以下代碼添加到onreadystatechange函數的末尾(在if語句中,檢查值爲4)。例如:

request.onreadystatechange = function() { 

if (request.readyState == 4) { 

    var xmlDoc = GXml.parse(request.responseText); 
      var points = xmlDoc.documentElement.getElementsByTagName("point"); 

      var polygonsToShow = []; 
      for (var i = 0; i < points.length; i++) {              
        var lat = parseFloat(points[i].getAttribute("lat")); 
        var lng = parseFloat(points[i].getAttribute("lng")); 
        var pid = points[i].getAttribute("id"); 
        for(var j = 0; j < polygons.length; j++) { 
          if(polygons[j].vt_bid == pid) { 
            polygonsToShow.push(j); 
          } 
        } 
        var point = new GLatLng(lat,lng);      
        var pname = points[i].getAttribute("name"); 
        var curMarker = createSearchMarker(point, pid, pname,getLetter(i));        
        map.addOverlay(curMarker); 
      } 
      //olays.buildings.checked = false; : Figure out some way to uncheck the buildings overlay checkbox? 
      for(var k = 0; k < polygons.length; k++) { 
        polygons[k].hide(); 
      } 

      for(var l = 0; l < polygonsToShow.length; l++){ 
        polygons[polygonsToShow[l]].show(); 
      } 

      searchResults = new HtmlControl('<div style="background-color:white; border:solid 1px grey; padding:2ex; overflow:auto; width:125px; margin:1px; font-size:14px;"><img align="right" style="cursor: pointer;" src="http://www.thebort.com/maps/images/close.gif" onclick="closeSearch()"><strong>Search</strong><br/>' + side_bar_html + '</div>', {selectable:true}); 
      map.addControl(searchResults, new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(20, 70))); 
}