StarlingMVC的显示对象注入失败问题分析

StarlingMVC是基于Starling的MVC框架,具有轻量的Ioc依赖注入功能,Bean是注入的基本单位。

先看看StarlingMVC的构造方法:

StarlingMVC(rootLayer:DisplayObjectContainer=null,
            config:StarlingMVCConfig=null,
            beanProviders:Array=null,
            customProcessors:Array=null)

StarlingMVC会自动对add到rootLayer的显示对象进行Bean预处理,也就是在初始化StarlingMVC时无需将显示对象传入beanProviders也能获得Bean一样的效果。比如我们有个LoginView.as如下:

public class LoginView extends Sprite
{
    [Dispatcher]
    public var dispatcher:EventDispatcher;

    [PostConstruct]
    public function init():void
    {
        dispatcher.addEventListener(EventName.GAME_START, onGameStart);
    }

    private function onGameStart():void
    {
        trace("游戏开始了!");
    }
}

LoginView的两段使用代码如下

方式A:

var scene:Scene = new Scene();
var loginView:LoginView = new LoginView();
rootLayer.addChild(scene);
scene.addChild(loginView);

方式B:

var scene:Scene = new Scene();
var loginView:LoginView = new LoginView();
scene.addChild(loginView);
rootLayer.addChild(scene);

使用“方式B”时LoginView.as第9行会异常,dispatcher为null。而“方式A”正常注入。为什么?继续往下看。

StarlingMVC自动识别显示对象并进行Bean预处理,是基于Event冒泡。实例化StarlingMVC时,StarlingMVC会对rootLayer添加Event.ADDED事件监听。在rootLayer层统一捕获子级addChild信息,再进行Bean预处理。

问题就出在Event.ADDED的冒泡上。“方式A” rootLayer可以捕获到scene、loginView的Event.ADDED事件冒泡;“方式B”rootLayer只能捕获到scene的事件冒泡。说到这里我们应该已经明白,事件冒泡机制决定了我们编码时注意:

若要让一个显示对象具有Bean特性,将其add到父级时请确保父级已经在rootLayer的显示列表树中

标签:flash, starlingmvc, 事件冒泡

添加新评论