2011-07-22 15 views
11

Lo siento si esto es trivial, pero soy nuevo en JS y he tenido este problema durante unas horas sin resultado.API de Google Maps - Problemas con las matrices e InfoWindows

function initialize() { 
    geocoder = new google.maps.Geocoder(); 
    var latlng = new google.maps.LatLng(-34.397, 150.644); 
    var myOptions = { 
    zoom: 12, 
    center: latlng, 
    mapTypeId: google.maps.MapTypeId.ROADMAP 
    } 
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); 
} 

var markersArray = []; 
var infowindowArray = []; 

function addMarker(location) { 
    marker = new google.maps.Marker({ 
    position: location, 
    map: map 
    }); 
    markersArray.push(marker); 
} 

function addInfowindow(string) { 
    infowindow = new google.maps.InfoWindow({content: string}); 
    infowindowArray.push(infowindow); 
} 

function findvenues(latitudelongitude) { 
$.get("venuefinder.php", { latlong:latitudelongitude.Ka+","+latitudelongitude.La }, function(data){ 
    var myObject = eval('(' + data + ')'); 
    for(x in myObject.response.venues){ 
     var latlonglocation = new google.maps.LatLng(myObject.response.venues[x].location.lat,myObject.response.venues[x].location.lng); 
     addMarker(latlonglocation); 
     addInfowindow(myObject.response.venues[x].name); 
     google.maps.event.addListener(markersArray[x], 'click', function() {infowindowArray[x].open(map,markersArray[x]);}); 
     console.log(markersArray[x],infowindowArray[x]); 
    } 
}); 

Cuando se invoca findvenues, se deben agregar los eventos de clic de infowindow. Cuando hago clic en los iconos, siempre se abre la misma ventana de información del último elemento en la matriz de infowindows.

Sin embargo, si entro en forma manual en el siguiente código, funciona:

google.maps.event.addListener(markersArray[0], 'click', function() {infowindowArray[0].open(map,markersArray[0]);}); 
google.maps.event.addListener(markersArray[1], 'click', function() {infowindowArray[1].open(map,markersArray[1]);}); 

necesito que esto sea dinámico, aunque ... ¿Qué estoy haciendo mal? Avíseme si la pregunta no está clara y haré todo lo posible para aclararla.

Respuesta

20

cambio que llaman a "addListener" en el bucle:

 google.maps.event.addListener(markersArray[x], 'click', function() {infowindowArray[x].open(map,markersArray[x]);}); 

a esto:

 google.maps.event.addListener(markersArray[x], 'click', (function(x) { 
     return function() { 
      infowindowArray[x].open(map,markersArray[x]); 
     } 
     })(x)); 

Mediante la introducción de otra función de esa manera, se crea un nuevo abanico de posibilidades. Eso "congela" el valor de "x" que ingresas para que la función devuelta (la función del controlador real que se pasará a la API de Google, en otras palabras) tenga acceso a su propia "x", separada de todos los demás controladores establecidos en ese bucle.

Si no hace eso, todos los controladores comparten exactamente la misma "x", y eso claramente no funciona.

editar — hay otras formas de hacerlo. Se puede escribir que la función adicional como algo totalmente separado:

function makeMapListener(window, map, markers) { 
    return function() { window.open(map, markers); }; 
} 

A continuación, la declaración en su bucle se vería así:

google.maps.event.addListener(markersArray[x], 'click', makeMapListener(inforwindowArray[x], map, markersArray[x])); 

La parte importante de ella es hacer una copia de la variable (s) que cambian durante el ciclo antes de construir la función del controlador.

+0

Gracias por esto. Entonces, si entiendo esto correctamente, debo pasar "x" a la función en el tercer argumento de addListener? ¿Por qué no es simplemente function (x) {infowindowArray [x] ...? –

+0

Al agregar otra capa como esa, crea un nuevo ** scope ** - eso significa que hace una ** copia ** de la variable "x" del bucle, de modo que la función de devolución de llamada tiene su propio para trabajar con . Extenderé la respuesta con otra posibilidad. – Pointy

+1

Supe esto porque tengo el mismo problema a mano, y ni siquiera * pensaba * sobre el alcance del nombre ... gracias por hacerme sentir más tonto de lo que ya soy, pero + por una buena respuesta. – jonc

Cuestiones relacionadas