我尝试从舞台上的某个组件调度自定义事件,并且我注册了另一个组件来监听它,但另一个组件没有得到该事件。
这是我的代码;我错过了什么?
public class Main extends MovieClip //main document class
{
var compSource:Game;
var compMenu:Menu;
public function Main()
{
compSource = new Game;
compMenu = new Menu();
var mc:MovieClip = new MovieClip();
addChild(mc);
mc.addChild(compSource); // the source of the event - event dispatch when clicked btn
mc.addChild(compMenu); //in init of that Movie clip it add listener to the compSource events
}
}
public class Game extends MovieClip
{
public function Game()
{
btn.addEventListener(MouseEvent.CLICK, onFinishGame);
}
private function onFinishGame(e:MouseEvent):void
{
var score:Number = Math.random() * 100 + 1;
dispatchEvent(new ScoreChanged(score));
}
}
public class Menu extends MovieClip
{
//TextField score
public function Menu()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
//on init add listener to event ScoreChanged
addEventListener(ScoreChanged.SCORE_GAIN, updateScore);
}
public function updateScore(e:ScoreChanged):void
{
//it never gets here!
tScore.text = String(e._score);
}
}
public class ScoreChanged extends Event
{
public static const SCORE_GAIN:String = "SCORE_GAIN";
public var _score:Number;
public function ScoreChanged( score:Number )
{
trace("new score");
super( SCORE_GAIN, true);
_score = score;
}
}
我不想写在Main
compSource.addEventListener(ScoreChanged.SCORE_GAIN, compMenu.updateScore);
因为我不希望compSource知道compMenu; compMenu有责任了解需要倾听的事件。
答案 0 :(得分:0)
游戏和菜单似乎位于事件链中的不同链上。事件泡沫向上,因为游戏和菜单是兄弟姐妹,他们将无法访问彼此的事件。
一种解决方案是让您从主屏幕将游戏参考发送到菜单。然后从该菜单中添加一个事件监听器。
答案 1 :(得分:0)
桑德罗是正确的,因为事件会冒泡而不是横向,你的Menu
永远不会看到事件。
一种可能的解决方案:由于Main
已经“知道”compSource
和compMenu
,您可以安全地通过主要类传递事件:
class Main{
public function Main()
{
compSource = new Game();
compSource.addEventListener(ScoreChanged.SCORE_GAIN, scoreGainHandler);
compMenu = new Menu();
//... rest of constructor
}
public function scoreGainHandler(event:ScoreChanged):void
{
compMenu.updateScore(event);
}
//... rest of class
这样,您的Game
和Menu
保持独立。
事实上,如果你以这种方式构建它,Menu
根本不需要听取分数变化事件,你可以只更改更新功能以获取分数变量:
class Menu{
public function updateScore(score:int):void
{
tScore.text = String(score);
}
//... etc