2009-11-04 2 views
0

Я пытаюсь передать текущее значение переменной при щелчке динамически созданного навигационного узла. Это должно быть просто целое число, но оно всегда приводит к значению последнего узла. Попробовали несколько разных методов для передачи значения, пользовательского прослушивателя событий, установщика, но я подозреваю, что это проблема закрытия. ;-)Проблема закрытия? - передача текущего значения переменной

function callGrid():void { 

    for (var i:Number = 0; i < my_total; i++) { 

     var gridnode_url = my_grid[i][email protected]; 
     var news_category= my_grid[i][email protected]; 
     var newstitle = my_grid[i][email protected]; 
     var news_content = my_grid[i]..news_content; 
     var news_image = my_grid[i]..news_image; 

     var gridnode_loader = new Loader(); 
     container_mc.addChild(gridnode_loader); 
     container_mc.mouseChildren = false; 
     gridnode_loader.load(new URLRequest(gridnode_url)); 
     gridnode_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, gridLoaded); 
     gridnode_loader.name = i; 

     text_container_mc = new MovieClip(); 
     text_container_mc.x = 0; 
     text_container_mc.mouseEnabled = false; 
     var textY = text_container_mc.y = (my_gridnode_height+18)*y_counter; 
     addChild(text_container_mc); 
     var tf:TextSplash=new TextSplash(newstitle,10,0,4); 
     container_mc.addChild(tf); 
     tf.mouseEnabled = false; 
     tf.height = my_gridnode_height; 
     text_container_mc.addChild(tf); 
     var text_container_mc_tween = new Tween(text_container_mc, "alpha", Strong.easeIn, 0,1,0.1, true); 

     gridnode_loader.x = (my_gridnode_width+5) * x_counter; 
     gridnode_loader.y = (my_gridnode_height+15) * y_counter; 

     if (x_counter+1 < columns) { 
      x_counter++; 
     } else { 
      x_counter = 0; 
      y_counter++; 
     } 
    } 
} 
function gridLoaded(e:Event):void { 
    var i:uint; 
    var my_gridnode:Loader = Loader(e.target.loader); 
    container_mc.addChild(my_gridnode); 
    _xmlnewstarget = my_gridnode.name; 

//|||||||||||||||||||||||||||||||||||||||| 
//when a particular grid node is clicked I need to send the current _xmlnewstarget value to the LoadNewsContent function... 
//||||||||||||| |||||||||||||||||||||||| 

    my_tweens[Number(my_gridnode.name)]=new Tween(my_gridnode, "alpha", Strong.easeIn, 0,1,0.1, true); 
    my_gridnode.contentLoaderInfo.removeEventListener(Event.COMPLETE, gridLoaded); 
    my_gridnode.addEventListener(MouseEvent.CLICK, loadNewsContent); 

} 

function loadNewsContent(e:MouseEvent):void { 
    createNewsContainer(); 
    getXMLNewsTarget(); 
    news_category = my_grid[_xmlnewstarget][email protected]; 
    var tfnews_category:TextSplash=new TextSplash(news_category,20,16,32,false,false,0xffffff); 
    tfnews_category.mouseEnabled = false; 

    newstitle = my_grid[_xmlnewstarget][email protected]; 
    var tftitle:TextSplash=new TextSplash(newstitle,20,70,24,false,false,0x333333); 
    news_container_mc.addChild(tftitle); 
    tftitle.mouseEnabled = false; 

    news_content = my_grid[_xmlnewstarget]..news_content; 
    var tfnews_content:TextSplash=new TextSplash(news_content,20,110,20,true,true,0x333333,330); 
    news_container_mc.addChild(tfnews_content); 
    tfnews_content.mouseEnabled = false; 
    news_image = my_grid[_xmlnewstarget][email protected]_image; 
    loadNewsImage(); 
    addChild(tfnews_category); 
    addChild(tftitle); 
    addChild(tfnews_content); 

    var news_container_mc_tween = new Tween(news_container_mc, "alpha", Strong.easeIn, 0,1,0.3, true); 
    news_container_mc_tween.addEventListener(Event.INIT, newsContentLoaded); 
} 

ответ

5

Я не буду пытаться прочитать код (пытаться работать на вашем форматировании, даже если это просто отступы), но я приведу упрощенный пример:

for (var i = 0; i < my_total; i++) { 
    var closure = function() { 
     // use i here 
    } 
} 

Как вы говорите, когда вызывается closure, оно будет содержать последнее значение i (которое в этом случае будет my_total). Сделайте это вместо того, чтобы:

for (var i = 0; i < my_total; i++) { 
    (function(i) { 
     var closure = function() { 
      // use i here 
     } 
    })(i); 
} 

Это создает другую функции внутри цикла, который «захватывает» текущее значение i так, что ваше замыкание может относиться к этому значению.

См. Также How does the (function() {})() construct work and why do people use it? для получения аналогичных примеров.

+0

Итак, в итоге :) Области *, а не * переменные, «закрыты» в Javascript, и только новое объявление функции может создать новую область. – 2009-11-04 01:44:21

+0

Спасибо, Грег за функцию закрытия, что действительно помогает. Я добавил код, убедился, что преобразование типа верное и добавлен сеттер для переменной _xmlnewstarget. Я создал идеальное колесо рулетки! Значения изменяются для 5 узлов 24130, 01432, 04312, 02143, 02143, 14302, 02143, 21403, 43021, 24310, 02143, 14302, 02143, 43021 ... последнее значение является значением для _xmlnewstarget ... – martin

+0

Мне удалось разобраться в этом по другому пути. Я добавил идентификатор новостей в xml для каждого элемента новостей, ссылаясь на это на текстовый контейнер - text_container_mc.id = my_grid [i]. @ Id; Затем я прыгнул прямо, чтобы загрузитьNewsContent с text_container_mc.addEventListener (MouseEvent.CLICK, loadNewsContent); а затем в этой функции связаны текстовые поля, используя e.target.id - newstitle = my_grid [e.target.id]. @ newstitle; Теперь мне просто нужно разобраться в обратном направлении.но я думаю, что эта проблема сортируется ;-) спасибо – martin

0

Umm, как уже упоминалось выше, код немного плотный, но я думаю, что у вас может быть проблема с преобразованием типа между строкой и целыми числами, является ли «последнее значение» всегда 0? попробуйте внести эти изменения и дайте мне знать, как вы поживаете.

// replace this gridnode_loader.name = i; 
gridnode_loader.name = i.toString(); 

// explictly type this as an int 
_xmlnewstarget = parseInt(my_gridnode.name); 

// replace this: my_tweens[Number(my_gridnode.name)] = new Tween(...... 
my_tweens[parseInt(my_gridnode.name)] = new Tween(); 

О, и я думаю, что это само собой разумеется, что вы должны массово реорганизовать этот блок кода, как только вы получили его работы.

Edit: после дальнейшего изучения, я думаю, что вам нужно это

//replace this: my_gridnode.addEventListener(MouseEvent.CLICK, loadNewsContent); 

var anonHandler:Function = function(e:MouseEvent):void 
{ 
    loadNewsContent(_xmlnewstarget); 

}; 
my_gridnode.addEventListener(MouseEvent.CLICK, anonHandler); 

Где ваш loadNewsContent изменилось заданы параметры от (e:MouseEvent) до (id:String)

+0

извините за компоновку кода, я постараюсь включить ваши предложения как можно скорее ;-) – martin

0

Во-первых, вам не нужно вызывать AddChild для того же самого загрузчика дважды (один раз в callGrid), а затем в (gridLoaded). Затем вы можете попробовать положить внутри loadNewsContent:
news_category = my_grid[int(e.target.name)][email protected];
вместо
news_category = my_grid[_xmlnewstarget][email protected];
Как _xmlnewstarget, кажется, больше области, поэтому он обновляется каждый раз, когда операция загрузки завершается.

+0

спасибо за это, я сделаю некоторое тестирование как можно скорее – martin

Смежные вопросы