2010-05-28 12 views
0

Le code ne fonctionnait pas à cause d'une requête asynchrone et d'un problème de portée variable. Je ne peux pas comprendre comment résoudre cela. Passer à la méthode $ .ajax avec async: false - pas une option. Je sais à propos des fermetures, mais comment je peux l'implémenter ici - je ne sais pas. J'ai vu tous les sujets ici sur les fermetures dans js et les problèmes d'async jQuery - mais toujours rien. Aidez-moi, s'il vous plaît. Voici le code:Requête jQuery async ajax et problème de retour (portée, fermeture)

var map = null; 
var marker; 
var cluster = null; 

function refreshMap() 
{ 
    var markers = []; 
    var markerImage = new google.maps.MarkerImage('/images/image-1_32_t.png', new google.maps.Size(32, 32)); 

    $.get('/get_users.php',{},function(data){ 
     if(data.status == 'error') 
      return false; 

     var users = data.users; // here users.length = 1 - this is ok; 
     for(var i in users) 
     { 
      //here I have every values from users - ok 
      var latLng = new google.maps.LatLng(users[i].lat, users[i].lng); 
      var mark = new google.maps.Marker({ 
       position: latLng, 
       icon: markerImage 
     }); 

      markers.push(mark); 
      alert(markers.length); // length 1 
     } 

    },'json'); 

    alert(markers.length); // length 0 
    //if I have alert() above - I get result 

    cluster = new MarkerClusterer(map, markers, 
    { 
     maxZoom: null, 
     gridSize: null 
    }); 
} 

Merci.

+0

Quel est le problème? Quel comportement voulez-vous/attendez-vous? – kevingessner

Répondre

1

Il suffit de déplacer ce code:

cluster = new MarkerClusterer(map, markers, 
{ 
    maxZoom: null, 
    gridSize: null 
}); 

Dans la fonction de rappel (où votre première alerte)

Le problème est que, avec une demande de async le code continuera à exécuter même si la demande a pas achevé. Donc, votre variable markers n'est pas définie correctement tant que votre fonction de rappel anonyme n'est pas exécutée.

+0

Oui, vous avez raison. Fonctionne bien. Je vous remercie. Honte à moi. – GiN

+0

Regardez, mais que se passe-t-il si j'ai besoin de pousser des données dans des marqueurs var à partir de $ .get (..) scope? – GiN

+0

Ensuite, vous devrez déplacer cette variable vers une portée plus élevée que celle dont vous avez besoin pour la référencer. – joshperry

0

Tout votre code qui doit traiter markers doit être dans votre fonction de rappel. Cette ligne de code:

alert(markers.length); // length 0 

est exécuté avant l'appel retourne Ajax (à savoir avant que le rappel est exécuté).


Cela signifie que votre code devrait ressembler à ceci:

$.get('/get_users.php',{},function(data){ 
    if(data.status == 'error') 
     return false; 

    var users = data.users; // here users.length = 1 - this is ok; 
    for(var i in users) 
    { 
     //here I have every values from users - ok 
     var latLng = new google.maps.LatLng(users[i].lat, users[i].lng); 
     var mark = new google.maps.Marker({ 
      position: latLng, 
      icon: markerImage 
     }); 

     markers.push(mark); 
     alert(markers.length); // length 1 

     cluster = new MarkerClusterer(map, markers, 
        { 
          maxZoom: null, 
          gridSize: null 
        }); 

     // more with cluster here 
    } 
},'json'); 

Si vous définissez ou modifier des variables dans un rappel Ajax, ne reposent pas sur leurs valeurs en dehors du rappel.

+0

Déjà fait. merci) – GiN