2010-03-24 4 views
0

La fonction que j'ai appelée à l'intérieur jquery renvoie undefined. J'ai vérifié la fonction et elle renvoie les données correctes quand je l'ai firebugged.Fonction à l'intérieur jquery renvoie undefined

function addToPlaylist(component_type,add_to_pl_value,pl_list_no) 
    { 
     add_to_pl_value_split = add_to_pl_value.split(":"); 

     $.ajax({ 
      type: "POST", 
      url: "ds/index.php/playlist/check_folder", 
      data: "component_type="+component_type+"&value="+add_to_pl_value_split[1], 
      success: function(msg) 
      { 
       if(msg == 'not_folder') 
       { 
        if(component_type == 'video') 
        { 
         rendered_item = render_list_item_video(add_to_pl_value_split[0],add_to_pl_value_split[1],pl_list_no) 
        } 

        else if(component_type == 'image') 
        { 
         rendered_item = render_list_item_image(add_to_pl_value_split[0],add_to_pl_value_split[1],pl_list_no) 
        } 
       } 
       else 
       { 
        //List files from folder 
        folder_name = add_to_pl_value_split[1].replace(' ','-'); 

        var x = msg; // json 
        eval('var file='+x); 

        var rendered_item; 

        for (var i in file) 
        { 
         //console.log(file[i]); 
         if(component_type == 'video') 
         { 
          rendered_item = render_list_item_video(folder_name+'-'+i,file[i],pl_list_no) + rendered_item; 
         } 

         if(component_type == 'image') 
         { 
          rendered_item = render_list_item_image(folder_name+'-'+i,file[i],pl_list_no) + rendered_item; 
         } 
        } 
       } 

       $("#files").html(filebrowser_list); //Reload Playlist 

       console.log(rendered_item); 

       return rendered_item; 
      }, 
      error: function() 
      { 
       alert("An error occured while updating. Try again in a while"); 
      } 
     })   
    } 

$('document').ready(function() 
{ 
    addToPlaylist($('#component_type').val(),ui_item,0); //This one returns undefined 
}); 
+2

Première note: ne pas utiliser 'eval' pour analyser JSON: http://www.json.org/js.html – Matchu

+0

merci pour cette info Matchu! – steamboy

Répondre

2

Vous effectuez votre requête via AJAX, qui est par définition asynchrone. Cela signifie que vous revenez de la fonction avant la fin de la requête AJAX. En fait, votre déclaration de retour n'a aucun sens car elle revient de la fonction de rappel, et non votre fonction addToPlaylist.

Vous avez plusieurs choix. Le premier est meilleur. Tout d'abord, vous pouvez travailler avec la nature asynchrone de la requête AJAX et passer un rappel dans votre méthode addToPlaylist (tout comme vous passez dans le rappel anonyme à la fonction ajax) et avoir le rappel AJAX, appelez cette fonction au lieu de faire le retour. Ainsi, votre requête se termine de manière asynchrone et ne verrouille pas votre navigateur pendant qu'il se déroule. Ensuite, vous pouvez ajouter l'option aSync: false à l'appel ajax. Cela forcera l'appel AJAX à s'exécuter de manière synchrone (essentiellement, il boucle juste jusqu'à ce que l'appel retourne puis appelle votre callback). Si vous faites cela, vous devez capturer une variable locale dans votre fonction addToPlaylist à l'intérieur de la fonction de rappel et lui affecter la (les) valeur (s) à partir du rappel. À la fin de la fonction addToPlaylist, renvoyez cette variable comme résultat.

function addToPlaylist(component_type, add_to_pl_value, pl_list_no) 
{ 
    ...yada yada yada... 
    var result = null; 
    $.ajax({ 
     aSync: false, 
     ... 
     success: function(data) { 
      ... 
      result = rendered_item; 
     } 
    }); 

    return rendered_item; 
} 
+0

Merci deceze et tvanfosson! maintenant je le comprends. Mais comment appeler le rappel ajax sur votre première méthode? – steamboy

+0

Le rappel est 'cb'. Je l'ai montré invoqué en utilisant 'apply'. – tvanfosson

+0

J'ai fait cette addToPlaylist ($ ('# component_type'). Val(), ui_item, 0, cb); mais revient encore indéfini. Je ne suis pas sûr de savoir comment le faire. Appréciez votre aide beaucoup. – steamboy

5

La fonction addToPlaylist ne le fait pas return quoi que ce soit. Il effectue une requête asynchrone, qui exécute éventuellement une fonction de rappel, qui renvoie quelque chose. La fonction addToPlaylist d'origine est longue et renvoyée au moment où cela se produit, et la fonction de rappel ne renvoie à personne.

I.e. le code success: function(msg) { } s'exécute dans un contexte différent et plus tard que la fonction addToPlaylist environnante.

Essayez ceci pour le voir en action:

function addToPlaylist() { 
    $.ajax({ 
     ... 
     success : function() { 
      alert('second'); // comes after 'first' 
      return null;  // returns to nobody in particular 
     } 
    }); 
    alert('first');  // comes before 'second' 
    return 'something'; // can only return here to caller 
} 
1

Je suis d'accord avec deceze. Ce que vous devez faire est d'effectuer les actions nécessaires pour rendered_item dans la fonction de succès plutôt que de compter récupérer quelque chose à partir de addToPlayList().

Questions connexes