如何在以下代码结构中访问变量“abc”

时间:2012-09-10 12:41:40

标签: actionscript-3


1)首先,我不想使用CustomEvent类。我正在寻找一些不使用CustomEvent的解决方案。

2)其中一个解决方案是在ClassA中使用abc变量。然后直接通过ClassA调度(rathar而不是说classB.dispatchEvent())。但仍然在寻找是否有比这更好的解决方案。


//Frame1 code :
import flash.events.Event;

var classA:ClassA = new ClassA() ;

classA.addEventListener("hello", hello); 
classA.init();
function hello(e:Event)
{
    trace(e.currentTarget.abc); //<<<< NEVER EXECUTED
}

//classA
package
{
    import flash.display.MovieClip;
    import flash.events.Event;

    public class ClassA extends MovieClip 
    {

        var classB:ClassB ; 

        public function ClassA()
        {
            classB = new ClassB(); 

        }

        public function init()
        {
            classB.dispatchEvent( new Event("hello"));
        }

    }
}

//classB
package
{
    import flash.display.MovieClip;
    public class ClassB extends MovieClip
    {
        public var abc:Number =123;
        public function ClassB()
        {


        }




    }
}

2 个答案:

答案 0 :(得分:3)

在让您的示例工作之前,您缺少几个关键概念。首先,您要在ClassB的实例上调度该事件,但是您正在侦听ClassA的实例。因此,它们必须以某种方式相关,以便在调度事件时对事件进行适当的编排。 一种方法是使用event bubbling。有一点需要注意的是,原生事件冒泡只适用于DisplayObjects,但是你的两个类都继承自MovieClip,所以这没什么大不了的。

首先,您必须了解冒泡事件的运作方式。一个简单的解释是事件从显示层次结构的顶部开始,从显示树中向捕获朝向元素,它们最终在目标上调度,然后它们转过来并且 bubble 以相反的方向退出。

这意味着您的ClassB实例必须是ClassA。因此,您需要更改的第一件事是在ClassA构造函数中:

    public function ClassA()
    {
        classB = new ClassB();
        addChild(classB);
    }

接下来,当您发送事件时,您需要明确地说它是一个冒泡事件,否则它将在目标上触发,既不捕获也不通过显示堆栈冒泡

    public function init()
    {
        classB.dispatchEvent( new Event("hello", true));
    }

true的第二个参数将事件设置为冒泡事件。

最后,您需要更改处理程序。现在,它正在使用e.currentTarget,在这种情况下,这不会是你期望的(通常是,它被认为)。

您必须了解e.targete.currentTarget之间的区别。 e.target是事件的实际目标,与其冒泡或捕获的方式无关。另一方面,e.currentTarget目前处理事件的元素。因此,在您的情况下,e.currentTargetClassA的实例(事件处理程序实际附加到的实例),e.targetClassB的实例(实例是事件已发送)。在活动生命周期中,e.currentTarget会随着事件的变化而变化,但e.target应该始终相同。

在这种情况下,您希望引用事件的实际目标,而不是当前正在处理事件的元素。因此,您需要将处理程序更改为:

function hello(e:Event)
{
    trace(e.target.abc);
}

然后它应该工作。你可以找到一个工作example here来封装我所描述的变化。

如果这些类不是DisplayObjects,那么您将不得不采取不同的方法 - 通过使用信号模式或手动侦听重新触发ClassA内的事件。

答案 1 :(得分:0)

首先,您要向classA添加一个事件监听器,但您的classA init方法要求classB调度一个事件,这就是您的代码无法执行的原因。如果你想捕捉hello事件,你应该做类似

的事情
public function init()
    {
        this.dispatchEvent( new Event("hello"));
    }

或者你应该在classB上注册监听器(这不在范围内,所以没有代码建议)。

在ActionScript中,传输信息的最佳方法是使用自定义事件,因此我的建议是重新评估您对自定义事件的决定。