2016-08-19 28 views
0

我想爲Google地圖添加不同顏色的標記;如果地址是出租屋(「Y」),並且地址屬於私人廣告客戶(「N」),則添加紅色標記。我認爲這可以很容易地通過IF條件來完成,但不知何故它不起作用,我無法找出解決方案。 if (usertypes[x]=="Y") {}未被識別,因此它會自動跳轉到else {},這就是爲什麼現在結果始終爲藍色。添加Google地圖標記 - JavaScript'IF'在'FOR'循環中不起作用

代碼:

var addresses = ['address1', 'address2', 'address3', 'address4', 'address5']; 
 
var usertypes = ['Y', 'N', 'Y', 'Y', 'N']; 
 
var bounds = new google.maps.LatLngBounds(); 
 

 
// the loop: 
 
for (var x = 0; x < addresses.length; x++) { 
 
    $.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address=' + addresses[x] + '&sensor=false', null, function(data) { 
 
    var p = data.results[0].geometry.location 
 
    var latlng = new google.maps.LatLng(p.lat, p.lng); 
 

 
    // set red marker if the advertiser is a private user: 
 
    if (usertypes[x] == "Y") { 
 
     new google.maps.Marker({ 
 
     position: latlng, 
 
     map: map, 
 
     icon: 'http://maps.google.com/mapfiles/ms/icons/red-dot.png', 
 
     title: 'item position' 
 
     }); 
 

 
     bounds.extend(latlng); 
 

 
     // set blue marker if it is a rental house: 
 
    } else { 
 
     new google.maps.Marker({ 
 
     position: latlng, 
 
     map: map, 
 
     icon: 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png', 
 
     title: 'item position' 
 
     }); 
 
     
 
     bounds.extend(latlng); 
 
    } 
 
    }); 
 
} 
 

 
map.fitBounds(bounds);

感謝您的幫助:)

+1

你有沒有看過'usertypes [x]'?你能確認它是否有「Y」的確切值?我很確定'如果'陳述不會突然停止正常工作。 –

+0

是的,在控制檯中它爲我提供了正確的值 –

+1

然後它可能有一個或多個空間。另外,'$ .getJSON'完成時'x'不會是正確的值。 [閱讀這個問題,找出原因。](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) –

回答

2

你的問題是,你的回調異步執行,Ajax請求完成之後。由於這也是在循環完成後,此時變量x的值始終等於addresses.length

這裏有一個簡單的代碼片段,剝奪了所有的谷歌特定的東西,演示該問題:

var addresses = ['address1', 'address2', 'address3', 'address4', 'address5']; 
 
var usertypes = ['Y', 'N', 'Y', 'Y', 'N']; 
 

 
for (var x = 0; x < addresses.length; x++) { 
 
    setTimeout(function() { 
 
    if (usertypes[x] == "Y") { 
 
     console.log('red', x); 
 
    } else { 
 
     console.log('blue', x); 
 
    } 
 
    }, 1); 
 
}

運行時,這個片段記錄blue 5五次到控制檯。但是,如果刪除setTimeout()並只是同步調用該功能,則會獲得預期輸出(red 0blue 1red 2red 3blue 4)。

當然,由於您使用的是Ajax,因此您無法真正做到這一點。相反,您需要以某種方式「凍結」回調中的x的值。要做到這一點的方法之一是把它作爲參數傳遞到(同步)包裝函數:

var addresses = ['address1', 'address2', 'address3', 'address4', 'address5']; 
 
var usertypes = ['Y', 'N', 'Y', 'Y', 'N']; 
 

 
for (var x = 0; x < addresses.length; x++) { 
 
    (function (x) { 
 
    setTimeout(function() { 
 
     if (usertypes[x] == "Y") { 
 
     console.log('red', x); 
 
     } else { 
 
     console.log('blue', x); 
 
     } 
 
    }, 1); 
 
    })(x); 
 
}

每次包裝函數被調用的循環中,一個名爲x新變量在它內部創建(屏蔽相同名稱的外部循環計數器變量)以將傳遞到該函數的值存儲爲其參數。但是由於這個值僅僅是外層x的當前值,所以最終效果是將包裝器中的x的值鎖定爲包裝器被調用時外層x的值。

另一種選擇,在現代的JavaScript,將使用.forEach()重寫循環:

var addresses = ['address1', 'address2', 'address3', 'address4', 'address5']; 
 
var usertypes = ['Y', 'N', 'Y', 'Y', 'N']; 
 

 
addresses.forEach(function (address, x) { 
 
    setTimeout(function() { 
 
    if (usertypes[x] == "Y") { 
 
     console.log('red', x); 
 
    } else { 
 
     console.log('blue', x); 
 
    } 
 
    }, 1); 
 
});

這裏,.forEach回調函數有效地充當包裝功能,每次調用它有自己的獨立x。作爲獎勵,代碼也看起來更整齊一些。

+0

這個答案很有希望。然而,我還沒有真正進入這個話題,我不知道在哪裏和/或我應該如何插入這些行到我的代碼。 –

+0

我的片段中的'setTimeout()'是一個替代你的'$ .getJSON()'。 (兩者都採用回調函數,並將其安排在以後用於異步執行。)您應該將整個回調包裝在包裝函數中。 –