доступ к переменным изменениям, сделанным из встроенной функции в JavaScript - PullRequest
0 голосов
/ 23 декабря 2009

Я пытаюсь передать локальные переменные встроенной функции в 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);

}

Проблема в том, что я продолжаю получать artistIdArray.length = 0, даже если элементы представляют собой несколько элементов, которые «оповещаются» после добавления в массив.

Как я уже сказал, я даже не знаю, возможно ли это даже без глобальных переменных или объектов. Есть идеи? Я совершенно не прав?

Редактировать: вся функция

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);  
}

Ответы [ 3 ]

4 голосов
/ 23 декабря 2009

ОБНОВЛЕНО : Теперь, когда вы опубликовали весь свой код. Ответ заключается в том, что вы вообще не должны хранить элементы во временном массиве, а создаете перетаскиваемый элемент для каждого элемента, когда возвращается вызов AJAX.

Проблема в том, что, хотя массив доступен внутри обратного вызова AJAX, код в конце функции (вне каждой) выполняется до завершения вызовов AJAX, и поэтому массив пуст. Если вы создаете каждый перетаскиваемый объект при возврате вызова, вам не нужна промежуточная переменная хранения, и перетаскиваемый объект создается при вставке в DOM. Другой альтернативой было бы сделать ваши AJAX-вызовы синхронными {aSync: false}, но это также потенциально связывало бы браузер до тех пор, пока не вернутся все элементы. Лучше, IMO, жить с асинхронной природой вызова AJAX и обрабатывать каждый элемент по мере его создания.

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()

}
1 голос
/ 23 декабря 2009

Я не могу определить проблему, возможно, она лежит где-то еще, чем в предоставленном (и отредактированном) коде.

Но поскольку вы уже используете jQuery, рассмотрите возможность их назначения в качестве "глобального" свойства jQuery.

var artistIdArray = [];

тогда будет

$.artistIdArray = [];

и его использование будет выглядеть как

$.artistIdArray.push(artistAbb);

вы можете в конце концов получить к нему доступ таким же образом

alert($.artistIdArray.length);
1 голос
/ 23 декабря 2009

Вам не нужно передавать значения вообще, просто ссылайтесь на них непосредственно во встроенной функции.

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);

}
...