2012-05-11 2 views
0

Je pense que cela dépend plus du timing que du code, donc je cherche vraiment des conseils sur la meilleure façon d'obtenir une réponse JSON.timing de la réponse JSON AJAX dans Jquery

<script type="text/javascript"> 

      $(window).load(function() { 
       $('#messages').append('<img src="images/loading.gif" alt="Currently Loading" id="loading" />'); 

       var ideaid = <?php echo $_GET['ideaid']; ?>; 
       $.ajax({ 

        url: 'sql/ajaxsql.php', 
        type: 'POST', 
        data: 'switch=commentList&ideaid=' + ideaid + '&filter=sortdate', 
        dataType: 'json', 

        success: function(result) { 
         var len = result.length; 
         var html; 
         console.log('length= ' + len); 
         $('#response').remove(); 
         console.log(result); 
         for(var i = 0; i < len; i++) { 
          var pic = '<img src="https://graph.facebook.com/' + result[i].user_id + '/picture&type=small" align="middle" />'; 
          var authname; 
          FB.api('/' + result[i].user_id + '?fields=name', function(AuthName) { 
           console.log(AuthName); 
           alert(AuthName.name); 
           authname = AuthName.name; 

          }); 
          html = '<p>' + result[i].comment + '<br><hr>Date Added: ' + result[i].date + ' by ' + pic + ' ' + authname + '<br><hr><hr></p>'; 
          $('#comms').append(html); 

         } 

         $('#loading').fadeOut(500, function() { 
          $(this).remove(); 

         }); 
        } 
       }); 

       return false; 
      }); 

     </script> 

Avec ce code, il se déclenche pour obtenir des commentaires concernant une certaine idée (idea_id). Les commentaires ne contient que l'identifiant des utilisateurs (facebook). Lorsque toutes les données sont de retour, le succès trie les données prêtes à imprimer à l'écran dans un certain ordre.

Dans le cadre du succès, j'ai la date, l'heure, l'image FB et le nom dans le cadre des informations sur l'auteur sous chaque commentaire.

Date et heure, fonctionne. Image en utilisant le graphique fonctionne, mais le nom est un peu en retard du chargement de la fenêtre, et manque donc son appel, donc revient comme indéfini, puis l'alerte apparaît avec le nom. Je comprends qu'ajax est censé faire cela.

Quel est le meilleur moyen de contourner ce problème.

Merci d'avance.

Andrew

EDIT

Je suis incapable de faire ce travail, même avec les suggestions ci-dessous.

EDIT AGAIN Vient de voir la nouvelle version mise à jour comme ci-dessous. aurait également travaillé. Mais j'ai passé une journée sur cette fonction et j'ose ne pas jouer.

Dès que le FB.api entre en jeu, je ne pouvais pas obtenir les valeurs de l'extérieur. J'ai donc adopté une approche différente.

Plutôt que ajax, j'utilise la requête du côté PHP qui récupère les données, y compris le uid et JSON demandé que, et boulonné sur la matrice (de mysql_fetch_array) comme suit:

  $gc_result = mysql_query($gc_query); 
    while ($result = mysql_fetch_array($gc_result)) { 
     $jsonURL = "https://graph.facebook.com/" . $result['user_id'] . "/"; 
     $json = json_decode(file_get_contents($jsonURL), true); 
     $result["name"] = $json['name']; 

     $data[] = $result; 
    } 

    echo json_encode($data); 

maintenant J'ai, je peux alors faire ce qui suit et l'appeler dans le jQuery:

for(var i = 0; i < len; i++) { 
    var pic = '<img src="https://graph.facebook.com/' + result[i].user_id + '/picture?type=small" align="middle" />'; 
    html = '<p>' + result[i].comment + '<br><hr>Date Added: ' + result[i].date + ' by ' + pic + ' ' + **result[i]['name']** + '<br><hr><hr></p>'; 
    $('#comms').append(html); 
         } 

tout cela fonctionne très bien, et je suis un jquery novice à la programmation et l'utilisation de l'API Facebook et JSON, mais même je suis assis en arrière et suis assez impressionné par cette solution. Avant que je sois emporté, y a-t-il des failles potentielles dans ceci, performance ou sécurité sage?

Merci encore à l'avance.

Andrew

Répondre

2

L'appel à FB.api est probablement asynchrone (une autre demande ajax), donc vous devez déplacer le code après à l'intérieur du rappel FB.api:

FB.api('/' + result[i].user_id + '?fields=name', function(AuthName) { 
    console.log(AuthName); 
    alert(AuthName.name); 
    authname = AuthName.name; 
    html = '<p>' + result[i].comment + '<br><hr>Date Added: ' + result[i].date + ' by ' + pic + ' ' + authname + '<br><hr><hr></p>'; 
    $('#comms').append(html); 
}); 

Vous avez également un problème de portée variable à cause de la boucle for. L'un des moyens de résoudre ce problème consiste à utiliser une fonction distincte pour créer le rappel.Ajouter ce droit après votre bloc $(window).load, avant </script>:

function createFbApiCallback(jsonResult) { 
    return function(AuthName) { 
     var authname = AuthName.name; 
     var pic = '<img src="https://graph.facebook.com/' + jsonResult.user_id + '/picture&type=small" align="middle" />'; 
     var html = '<p>' + jsonResult.comment + '<br><hr>Date Added: ' + jsonResult.date + ' by ' + pic + ' ' + authname + '<br><hr><hr></p>'; 
     $('#comms').append(html); 
    } 
} 

Puis changez votre boucle à ceci:

for(var i = 0; i < len; i++) { 
    FB.api('/' + result[i].user_id + '?fields=name', createFbApiCallback(result[i])); 
} 
+0

Cela fait longtemps que je n'ai pas utilisé FB.api, mais je me souviens que c'était le cas. Je suis 95% sûr qu'il est asynchrone – Stephen

+0

En déplaçant la balise de fin pour le FB.api, j'obtiens une erreur non définie sur le résultat [i] ?? –

+0

Etrange, il devrait être accessible. Essayez de définir un alias juste avant d'appeler 'FB.api':' var currentResult = result [i] ', puis utilisez-le dans le callback. – bfavaretto

0

Si vous devez exécuter du code qui repose sur une fonction de rappel dans une autre fonction de rappel, exécutez votre code dans la fonction de rappel la plus interne. Dans votre cas, déplacez tout ce qui est en dehors de la fonction de rappel de l'API FB pour qu'elle soit à l'intérieur, donc toute votre manipulation DOM est effectuée uniquement lorsque la réponse AJAX et la réponse FB.api sont toutes les deux retournées.

+0

Il ne peut pas tous aller entre, car il s'appuie sur l'instruction for pour obtenir la ligne correcte. Je comprends la logique, mais une fois que l'api est appelée, elle demande un uid qui n'est pas encore donné en tant qu'élément? –

+0

'pour (var i = 0; i '; var authname; console.log (AuthName); authname = AuthName.name; html ='

'+ résultat [i] .comment +'


date: '+ résultat [i] .date + 'par' + pic + '' + authname + '


'; $ ('# comms'). append (html); }); } ' Cela me donne une image qui est une erreur indéfinie à titre d'exemple? –