2009-12-23 5 views
0

J'essaie de transmettre des variables locales à une fonction inline en javascript et d'avoir cette fonction (inline) manipuler ces variables, puis pouvoir accéder aux variables modifiées dans le fonction contenant. Est-ce seulement possible? Voici un exemple du code que je travaille avec:accéder à des modifications de variables effectuées à partir d'une fonction inline en javascript

function addArtists(artist, request, origElm, xml){ 

//variables 
var artistIdArray = []; 

/*coding*/ 

//traverse xml 
$('element', xml).each(function(){ 

/*coding*/ 

$.ajax({ 
    /*parameters*/ 
    success: function(html) { 
    var artistAbb = html; 

    /*coding*/ 

    //add this element's id to the array of ids to make it draggable later 
    artistIdArray.push(artistAbb); 
    alert(artistIdArray[artistIdArray.length - 1]); 

}//end on success  

});//end ajax call 

});//end each(function() 

alert(artistIdArray.length); 

} 

Le problème est que je continue à recevoir artistIdArray.length = 0, même si des éléments sont plusieurs éléments sont « alertés » après ils sont ajoutés au tableau.

Comme je l'ai dit, je ne sais pas si c'est possible sans variables globales ou objets. Des idées? Est-ce que je me trompe totalement?

Edit: Fonction entière

function addArtists(artist, request, origElm, xml){ 

//variables 
var artistIdArray = []; 

//create ordered list 
//set new <ol>s class 
var olClass = "artists"; //holds the class of new <ol> 

//create id for new <ol> 
var olId = "artists"; //holds the id of new <ol> 

//create actual <ol> element 
var ol = $('<ol></ol>').attr('id',olId) 
         .addClass(olClass) 
         .appendTo(origElm); 

//create the <li> elements from the returned xml 
//create class for new <li>s, (just the request minus the 's') 
var liClass = request.substring(0, request.length-1); 
//traverse xml 
$('element', xml).each(function(){ 

    //create id for new <li> based on artist abbreviation 
    var artist = $(this).text();   

    $.ajax({ 
    url: "php/artistToAbb.php", 
     data: {artist: artist}, 
     dataType: "html", 
     async: true, 
     success: function(html) { 
    var artistAbb = html; 

     //create li   
    var li = $('<li></li>').attr('id', artistAbb) 
          .addClass(liClass) 
          .appendTo(ol); 

    //create arrow icon/button for li 
    var img = $('<img />').attr('id', artistAbb + 'ArrowImg') 
          .attr("src","images/16-arrow-right.png") 
          .attr('onclick', "expand(this, '" + artistAbb + "', 'years', 'danwoods')") 
          .addClass("expImg") 
          .appendTo(li);  

    var artistTxt = $('<h2>' + artist + '</h2>') 
         .addClass("artist_txt") 
         .attr('onMouseOver', 'catMouseOver(this)') 
         .attr('onMouseOut', 'catMouseOut(this)') 
         .appendTo(li); 

    //tag the ol element's class 
    $($(origElm)[0]).addClass('expanded'); 

    //add this element's id to the array of ids to make it draggable later 
    artistIdArray.push(artistAbb); 
    alert(artistIdArray[artistIdArray.length - 1]); 

    }//end on success  

});//end ajax call 

});//end each(function() 

//make newly added artist elements draggable 
for(var n = 0; n < artistIdArray.length; n++){ 
    //new Draggable(artistIdArray[n], {superghosting: true, detached: true, onEnd: catClearHighlight}); 
    alert(artistIdArray[n]); 
} 
alert(artistIdArray.length); 
} 
+0

D'accord. Avec le code ci-dessus, la valeur de artistNum est incrémentée dans la boucle ('call # 1' alerte correcte artistNum) mais une fois que le contrôle revient à la fonction contenant, la valeur modifiée est perdue ('call # 2' ' – danwoods

+0

Essayez de le passer en tant qu'objet au lieu de valeurs séparées et ils doivent être gérés "par référence" comme vous le souhaitez. –

+0

Vous appelez # 2 références globales 'artistNum', pas le local défini dans' addArtists' –

Répondre

4

MISE À JOUR: Maintenant que vous avez publié votre code entier. La réponse est que vous ne devriez pas du tout stocker les éléments dans le tableau temporaire, mais créer le draggable pour chaque élément lorsque l'appel AJAX retourne. Le problème est que si le tableau est accessible dans le rappel AJAX, le code à la fin de la fonction (en dehors de chaque) s'exécute avant que les appels AJAX soient terminés et que le tableau soit vide. Si vous créez chaque draggable au retour de l'appel, vous n'avez pas besoin de la variable de stockage intermédiaire et le draggable est créé lors de son insertion dans le DOM. L'autre alternative serait de rendre vos appels AJAX synchrones {aSync: false}, mais cela pourrait aussi potentiellement lier le navigateur jusqu'à ce que tous les éléments soient revenus. Mieux, IMO, de vivre avec la nature asynchrone de l'appel AJAX et gérer chaque élément comme il est créé.

function addArtists(artist, request, origElm, xml){ 

    //create ordered list 
    //set new <ol>s class 
    var olClass = "artists"; //holds the class of new <ol> 

    //create id for new <ol> 
    var olId = "artists"; //holds the id of new <ol> 

    //create actual <ol> element 
    var ol = $('<ol></ol>').attr('id',olId) 
          .addClass(olClass) 
          .appendTo(origElm); 

    //create the <li> elements from the returned xml 
    //create class for new <li>s, (just the request minus the 's') 
    var liClass = request.substring(0, request.length-1); 
    //traverse xml 
    $('element', xml).each(function(){ 

      //create id for new <li> based on artist abbreviation 
      var artist = $(this).text();    

      $.ajax({ 
     url: "php/artistToAbb.php", 
       data: {artist: artist}, 
       dataType: "html", 
       async: true, 
       success: function(html) { 
     var artistAbb = html; 

       //create li     
     var li = $('<li></li>').attr('id', artistAbb) 
           .addClass(liClass) 
           .appendTo(ol); 

     //create arrow icon/button for li 
     var img = $('<img />').attr('id', artistAbb + 'ArrowImg') 
           .attr("src","images/16-arrow-right.png") 
           .attr('onclick', "expand(this, '" + artistAbb + "', 'years', 'danwoods')") 
           .addClass("expImg") 
           .appendTo(li);  

     var artistTxt = $('<h2>' + artist + '</h2>') 
          .addClass("artist_txt") 
          .attr('onMouseOver', 'catMouseOver(this)') 
          .attr('onMouseOut', 'catMouseOut(this)') 
          .appendTo(li); 

     //tag the ol element's class 
     $($(origElm)[0]).addClass('expanded'); 

     new Draggable(artistAbb, {superghosting: true, detached: true, onEnd: catClearHighlight}); 

     }//end on success  

    });//end ajax call 

    });//end each(function() 

} 
+0

Mais serait-il possible d'accéder à ces valeurs modifiées dans la fonction conteneur? une fois la fonction interne exécutée, la fonction externe indique toujours artistIdArray.length est égal à 0 ... – danwoods

+0

@danwoods: Je pense que le problème principal est la nature asynchrone de la requête Ajax, lorsque vous essayez d'utiliser votre tableau, le havre de requête Ajax pas terminé, c'est pourquoi est vide ... – CMS

+0

exactement ce dont j'avais besoin. Merci – danwoods

1

Vous n'avez pas besoin de transmettre les valeurs, il suffit de les référencer directement dans la fonction inline.

function addArtists(artist, request, origElm, xml){ 

//variables 
var artistIdArray = new Array(); 
var artistNum = 0; 

/*coding*/ 

//traverse xml 
$('element', xml).each(function(){ 

        /*coding*/ 

    //add this element's id to the array of ids to make it draggable later 
    artistIdArray[artistNum] = "some value"; 
    //alert(artistNum); 
    artistNum++; 

}//end on success  

});//end ajax call 

});//end each(function() 

//test how many elements 
for(var n = 0; n < artistIdArray.length; n++) 
    alert(n); 

} 
+0

Je peux obtenir la fonction interne de lire la valeur des variables juste ne pas modifier ces valeurs (ie: artistNum est toujours 0) – danwoods

+0

réparé en partie, voir mon commentaire à ma propre question – danwoods

1

Je ne peux pas repérer le problème, il se trouve probablement quelque part ailleurs que dans la mesure du code proposé (et édité). Mais comme vous utilisez déjà jQuery, envisagez de les affecter en tant que propriété jQuery "global".

var artistIdArray = []; 

serait alors

$.artistIdArray = []; 

et l'utiliser doit ressembler à

$.artistIdArray.push(artistAbb); 

vous pourriez alors à l'accès final de la même façon

alert($.artistIdArray.length); 
+0

Merci pour l'info :) – danwoods

Questions connexes