关闭问题? - 传递变量的当前值

时间:2009-11-04 01:18:35

标签: actionscript-3 event-handling closures scope

当点击动态生成的导航“节点”时,我正在尝试传递变量的当前值。这需要只是一个整数,但它总是导致最后一个节点的值..尝试了一些不同的方法来传递值,一个自定义事件监听器,一个setter,但我怀疑它是一个闭包问题..帮助将不胜感激; - )

function callGrid():void {

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

        var gridnode_url = my_grid[i].@gridnode;
        var news_category= my_grid[i].@category;
        var newstitle = my_grid[i].@newstitle;
        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].@category;
    var tfnews_category:TextSplash=new TextSplash(news_category,20,16,32,false,false,0xffffff );
    tfnews_category.mouseEnabled = false;

    newstitle = my_grid[_xmlnewstarget].@newstitle;
    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].@news_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);
}

3 个答案:

答案 0 :(得分: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?

答案 1 :(得分:0)

嗯,如上所述,代码有点密集,但我想你可能在字符串和整数之间有一点类型转换问题,“最后一个值”总是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();

哦,我认为一旦你完成它就应该大规模重构这个代码块。

编辑:经过进一步研究后,我认为你需要这个

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

答案 2 :(得分:0)

首先,您不需要为同一个加载器调用addChild两次(一次在callGrid中),然后调用(gridLoaded)。然后你可以尝试放入loadNewsContent:
news_category = my_grid[int(e.target.name)].@category;
而不是news_category = my_grid[_xmlnewstarget].@category;由于_xmlnewstarget似乎是更大的范围,这就是为什么它得到了每次加载操作完成时都会更新。