2012-07-20 24 views
9

Estoy creando un mapa que carga & destruye los marcadores según el cuadro delimitador y el nivel de zoom. Tengo un problema real para que los marcadores se eliminen correctamente, a veces parece funcionar en ciertas situaciones.Google Maps API v3: los marcadores no se eliminan

Tengo un objeto que contiene la información del marcador, que también contiene el objeto marcador de google maps. Mi código detecta si el mercado debe eliminarse según el cuadro delimitador o el nivel de zoom. Establecí el objeto marcador en "setMap (null);" y usando firebug puedo ver que se está configurando, luego elimino por completo el objeto primario y la longitud de los datos de los objetos se actualiza correctamente.

Salgo a la consola Firebug cuando supuestamente se borra un marcador, parece estar funcionando y puedo ver que el marcador no se está reordenando desde la llamada ajax para los marcadores en el cambio del cuadro delimitador.

Sin embargo, si hago zoom en el mapa, a veces puedo ver que los marcadores se están quitando, si alejé el zoom, retrocedo con el mouse hacia abajo. O a veces los marcadores se eliminarán si hago zoom la primera vez, pero si amplío de nuevo y luego retrocedo, no se eliminan.

Debo estar haciendo algo mal con la lógica de mi código, estoy perplejo.

Puede ver la fuente de http://www.trailforks.com/map/test.php?lat=49.352247&lon=-123.202413 la JS es http://www.trailforks.com/map/includes/map.js

el código para eliminar un marcador está en la parte inferior

function clearMarkerMemory(mapItem, i) { 
    google.maps.event.removeListener(mapItem.lis); // remove stored listener 

    mapper.data[i].obj.setMap(null); // remove marker 
    mapper.data.splice(i, 1); 

    console.log("removed marker "+mapItem.icon+":"+mapItem.nid+' '+mapItem.name); 
}; 

añadí un poco más de depuración en la consola, pasando a un área simple del mapa con solo 2 marcadores http://www.trailforks.com/map/test.php?lat=49.641783767&lon=-123.49878636730955&z=14

Puedo ver los marcadores creados, luego mover el mapa ab y ver que los marcadores no se volvieron a crear porque se detectaron en el objeto marcador. Luego muevo la ventana gráfica para que uno de los marcadores esté fuera de la pantalla y puedo ver que el marcador se elimina y la longitud del objeto marcador se actualiza. Pero si vuelvo a desplazar el mapa sobre el marcador, aún está en el mapa.

enter image description here

+1

Tengo dificultades para reproducir el "error" si realmente hay errores. Eche un vistazo a su código y está bien escrito y AFAICS está haciendo lo correcto. No es que importe, pero ¿ha intentado establecer todo el objeto 'data [i]' en 'null' antes de empalmarlo fuera de la matriz? – dda

+0

+1 para una pregunta bien escrita e inteligente, por cierto ... – dda

+0

Para reproducir, vaya a este punto de vista http://www.trailforks.com/map/test.php?lat=49.344530719060245&lon=-123.1294569147949&z=13 y haga clic en el mouse para que todos los marcadores amarillos de la izquierda estén fuera de la pantalla. luego, arrastre el mapa hacia atrás en esa dirección, manteniendo presionado el mouse, para que la llamada ajax de marcadores no se active todavía, verá que todos los marcadores se han eliminado. Pero luego amplíe una vez y vuelva a intentarlo, y lo más probable es que se rompa, los marcadores permanecerán el 100% del tiempo. Aunque se eliminan del objeto mapper.data. – Canadaka

Respuesta

0

En vez de hacer:

google.maps.event.addListener(map, 'dragend', function() { refreshMarkers(); }); //refresh markers when user moves map 
google.maps.event.addListener(map, 'zoom_changed', function() { refreshMarkers(); }); //refresh markers when user moves map 

cambio a:

EDITAR, (después de los comentarios):

Para evitar que varias instancias del controlador de eventos que ocurren simultáneamente, se podría usar una variable global, de la siguiente manera:

google.maps.event.addListener(map, 'bounds_changed', function() { 
if (processing) { // var processing is global 
    return; 
} 
processing = true; 
refreshMarkers(); 
processing = false; 

}); //refresh markers when user moves map 

Esto debería cubrir ambas situaciones. Tal como está ahora, con dos oyentes de eventos diferentes, las llamadas AJAX podrían ser conflictivas, y usted podría lanzar una segunda llamada antes de que la primera se haya completado.

+0

el problema con el uso de "bounds_changed" es que comienza a llamar a TON de las llamadas ajax para cada pequeño movimiento del mouse, esto podría equivaler a cientos cuando el usuario suelta el mouse, "dragend". Pero lo he intentado de todos modos y el problema aún persiste, si me muevo por cargar un montón de marcadores y luego alejé, ninguno de los marcadores se eliminan incluso con el único oyente. También probé con solo habilitar dragend o zoom_changed. – Canadaka

+0

Eso se previene fácilmente con una variable global que indica que se está procesando un evento. (Ver la edición de mi respuesta). – Marcelo

+0

el código anterior aún no funciona, nunca parece ser cierto, y obtengo un tono de POST anulado en la consola de Firebug, el mapa es super laggy. Sería bueno tener solo un oyente, pero estoy bastante seguro de que mi problema con los marcadores que no eliminan no está relacionado con tener múltiples oyentes, ya que puedo generar el problema con solo 1 escucha activada. – Canadaka

3

Estuve luchando con un problema similar durante mucho tiempo hasta que me di cuenta de que el método setMap del marcador de mapa es asincrónico. Cuando lo llama e inmediatamente elimina cualquier referencia a ese objeto marcador, el recolector de basura del navegador interviene y lo limpia de la memoria y así evita que ocurra la operación de eliminación real.

Pruébelo simplemente comentando la línea con la llamada de empalme y ver si eso ayuda. Si ayuda, debería considerar retrasar la eliminación del objeto o, alternativamente, almacenar la referencia al objeto marcador hasta que realmente se elimine. ¿Cómo detectar si realmente se elimina? No tengo idea.

Espero que esto ayude!

Cuestiones relacionadas