2009-07-15 18 views
15

Posta kodu aramasından şehir + durum/bölge bilgilerini almak için Google Harita API'sini kullanıyorum. Sorun şu ki, bazı durumlarda posta kodu araması bir şehir adı almaz. Bir örnek 92625 (ABD). Şehir için tanımlanmamış bir hata olacaktır böylece anahtar Yerellik var olmadığından Bazı durumlardaJSON anahtarlarının/düğümlerinin var olup olmadığını kontrol edin

var g = new GClientGeocoder(); 
g.setBaseCountryCode('US'); 
g.getLocations('92625', function(response){ 
    if (response) { 
     var place = response.Placemark[0]; 
     var state = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName; 
     var city = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName; 
     GLog.write("City = "+city+" : State/Region = "+state+" : Country = " + g.getBaseCountryCode()); 
    } 
}); 

, yukarıda da belirtildiği gibi, sonuç bir şehir adı olmayacaktır. Bu hata, komut dosyasının geri kalanı çalışmasını engeller.

ben ...

if (place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality != null) 
     var city = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName; 
    else 
     var city = ''; 

bunu düzeltmek başardı ... ama bu diğer anahtarlar için de benzer bir hata hakkında bana paranoyak vardır. Örneğin: AdministrativeArea tanımlanmamışsa, yukarıdaki IF deyimi de tanımlanmamış bir hataya neden olur. Her Anahtar/Düğümün var olup olmadığını kontrol etmeli miyim? Dağınık bir yaklaşım gibi görünüyor, çünkü bu tuşların bazıları 5+ seviye derin ... bununla ilgili daha kolay bir yol var, belki de JQuery metodu aşina değil mi?

cevap

9

Alternatif olarak, bir işlev yapabilir, bu sana varsayılan verir p00ya'nın önerisinden daha az yazılsa da, tanımlanamayan nesneler etrafında küçük bir taş yığını olsa da ... belki de bunu şu şekilde değiştirebiliriz:

Yalnızca ilk sonuç bakıyorsun 210
function drill(p, a) { 
a = a.split(".");//add this 
for (i in a) { 
    var key = a[i]; 
    if (p[key] == null) 
    return ''; 
    p = p[key]; 
} 
return p; 
} 
var obj = {foo:{bar:{baz:"quux"}}}; 
var s = drill(obj, "foo.bar.baz"));//and you can use a simple property chain 
3

Tüm bu yuvalama seviyelerinde "delme" işlevini, bu kadar uzaklaşamazsa boş dizeye varsayılan bir işlev kullanabilirsiniz. Böyle

function valueOrDefault(val, def) { 
    if (def == undefined) def = ""; 
    return val == undefined ? def : val; 
} 

Sonra kullanmak: Şahsen

var place = response.Placemark[0]; 
var state = valueOrDefault(place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName); 
var city = valueOrDefault(place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName); 

, ben biraz daha güzel olduğunu düşünüyorum

function drill(p, a) { 
for (i in a) { 
    var key = a[i]; 
    if (p[key] == null) 
    return ''; 
    p = p[key]; 
} 
return p; 
} 
var obj = {foo:{bar:{baz:"quux"}}}; 
var s = drill(obj, ["foo", "bar", "baz"])); 
0

geocoder verir:

var place = response.Placemark[0]; 

getLocations() birkaç sonuçların listesini döndürür. İlki buna sahip değilse, önümüzdeki birkaç sonuçtan biri kesinlikle olacaktır.

+0

Yukarıdaki örnekte, 92625 için her zaman yalnızca 1 sonuç vardır. – Seth

3

Ben back2dos' yaklaşımı gibi ama ReferenceError s ile başarısız etmemek için onu geliştirilebileceğini düşünüyor:

function jPath(obj, a) { 
    a = a.split("."); 
    var p = obj||{}; 
    for (var i in a) { 
     if (p === null || typeof p[a[i]] === 'undefined') return null; 
     p = p[a[i]]; 
    } 
    return p; 
} 

// Tests 
var a = {b:{c:'Hello World!'}, c:null}; 

console.log(jPath(a, 'b.c')); // Hello World 
console.log(jPath(a, 'b.d')); // null 
console.log(jPath(a, 'e.f.g')); // null 
console.log(jPath(a, 'c'));  // null 

var z; 
console.log(jPath(z, 'c'));  // null 
fonksiyonunun Bu tür tür serbest baz olarak AJAX hizmetlerinden derin JSON dönüş yapılarını doğrulamak için mükemmeldir

veya YQL.

İlgili konular