2010-03-25 3 views
4

Je suis resté coincé dans ce problème pendant une heure. Je pense que c'est quelque chose qui se rapporte à la portée variable? Quoi qu'il en soit, voici le code:jQuery ajax() renvoie l'objet json à une autre fonction en cas de succès provoque une erreur

function loadRoutes(from_city) 
{ 
$.ajax(
{ 
    url: './ajax/loadRoutes.php', 
    async : true, 
    cache : false, 
    timeout : 10000, 
    type : "POST", 
    dataType: 'json', 
    data : 
    { 
     "from_city" : from_city 
    }, 
    error : function(data) 
    { 
     console.log('error occured when trying to load routes'); 
    }, 
    success : function(data) 
    { 
     console.log('routes loaded successfully.'); 
     $('#upperright').html(""); //reset upperright box to display nothing. 

     return data; //this line ruins all 

     //this section works just fine. 
     $.each(data.feedback, function(i, route) 
     { 
      console.log("route no. :" + i + " to_city : " + route.to_city + " price :" + route.price); 
      doSomethingHere(i);    
     }); 
    } 
}); 

}

La pour chaque section fonctionne très bien dans la région de rappel de succès. Je peux voir que la console Firebug affiche les identifiants d'itinéraire sans aucun problème.

Pour but découplage, je pense qu'il serait préférable de simplement renvoyer l'objet de données, au format JSON, à une variable dans la fonction de l'appelant, comme ceci:

//ajax load function 
function findFromCity(continent, x, y) 
{ 
console.log("clicked on " + continent + ' ' + x + ',' + y); 

$.ajax(
{ 
    url: './ajax/findFromCity.php', 
    async : true, 
    cache : false, 
    timeout : 10000, 
    type : "POST", 
    dataType : 'json', 
    data : 
    { 
     "continent" : continent, 
     "x"   : x, 
     "y"   : y 
    }, 
    error : function(data) 
    { 
     console.log('error occured when trying to find the from city'); 
    }, 
    success : function(data) 
    { 
     var cityname = data.from_city; 

     //only query database if cityname was found 
     if(cityname != 'undefined' && cityname != 'nowhere')  
     { 
      console.log('from city found : ' + cityname); 

      data = loadRoutes(cityname); 

      console.log(data); 
     } 
    } 
}); 
} 

Puis tout d'un coup, tout arrête de fonctionner! La console Firebug signale un objet de données comme "indéfini" ... n'a-t-il pas été assigné par l'objet retournant de la méthode loadRoutes (cityname)?

Désolé ma connaissance globale sur javascript est assez limitée, alors maintenant je suis juste comme un "imitateur" pour travailler sur mon code de façon amateur.

Édité: Ayant vu l'allusion de Nick, laissez-moi travailler dessus maintenant et voir comment ça se passe.

Modifié 2:

ours avec moi, toujours coincé dans ce:

//ajax load function 
function findFromCity(continent, x, y) 
{ 
console.log("clicked on " + continent + ' ' + x + ',' + y); 

var cityname = "nowhere"; //variable initialized. 

$.ajax(
{ 
    url: './ajax/findFromCity.php', 
    async : true, 
    cache : false, 
    timeout : 10000, 
    type : "POST", 
    dataType : 'json', 
    data : 
    { 
     "continent" : continent, 
     "x"   : x, 
     "y"   : y 
    }, 
    error : function(data) 
    { 
     console.log('error occured when trying to find the from city'); 
    }, 
    success : function(data) 
    { 
     cityname = data.from_city; 

     //only query database if cityname was found 
     if(cityname != 'undefined' && cityname != 'nowhere')  
     { 
      console.log('from city found : ' + cityname); 

      //data = loadRoutes(cityname); 

      //console.log(data); 
     } 
    } 
}); 

return cityname; //return after ajax call finished. 
} 

imprime console Firebug sur quelque chose intéressante:

nowhere 
from city found : Sydney 

Je pensais que l'ordre doit être au moins inversé comme ceci:

from city found : Sydney 
nowhere 

Donc, fondamentalement, la variable définie dans la région de succès a une portée complètement différente de la même variable à l'extérieur? Cela me semble bizarre au début mais maintenant je le vois.

encore, ne savent pas comment passer l'objet JSON sur le rappel de succès pour l'affecter à une autre variable ...

Conclusion: D'accord, je l'ai eu, en travaillant sur « passer par référence » à faire usage de l'effet de bord pour changer une variable transmise par paramètre de fonction maintenant ... Ce qui n'est pas directement lié à cette question.

Répondre

9

Le rappel success se produit lorsque l'appel ajax se termine, donc rien n'est réellement renvoyé par votre fonction, car cette instruction ne s'exécute que plus tard. Dans le scénario AJAX, vous devez obtenir l'objet de données, puis appeler ce qui doit être exécuté ensuite, car toutes les fonctions de rappel success ou complete se produiront après le code que vous exécutez, lorsque la réponse du serveur revient.

+0

bon point, il n'y a rien à y retourner ... – BenB

+0

Fait sens .... –

+0

@Nick Craver: changer le nom de la section de rappel de "succès" à "terminer" dans la fonction de l'appelant findFromCity (continent, x, y) ne résoudrait pas ce problème. les données sont toujours reconnues comme "indéfinies". –

1

Peut-être un problème de portée "de données".

Dans le deuxième exemple, quelles sont les données renvoyées par l'objet json, et laquelle est celle envoyée?

+0

@ BenB: le deuxième extrait de code est la fonction appelant qui appelle la fonction ajax "loadRoutes (from_city)", et attend l'objet json renvoyé par l'appelé. –

5

Vous pourriez peut-être essayer cette méthode:

function loadRoutes(parameters) 
{ 
    return $.ajax({ 
     type: "GET", 
     async: false, // This is important... please see ref below 

     // Other Settings (don't forget the trailing comma after last setting) 

     success: function() { 
      console.log('Success'); 
     }, 
     error: function() { 
      console.log('Error'); 
     } 
    }).responseText; 
} 

Donc, fondamentalement, « .responseText » est ajouté à la demande « de .ajax de $ » et la demande elle-même devient alors la valeur de retour.

Remarque: Cette utilisation - renvoyer le résultat de l'appel dans une variable - nécessite une requête synchrone (blocage). Utilisez donc 'async: false' dans les paramètres.

Pour retourner une valeur JSON, vous pouvez utiliser:

return $.parseJSON($.ajax({ 
    // Other settings here... 
}).responseText); 

Pour plus d'informations voir: http://api.jquery.com/jQuery.ajax.

Questions connexes