子对象中的AS3事件处理程序未触发

时间:2011-03-13 05:29:59

标签: actionscript-3

在学习AS3和事件处理时,也许我错过了一些方面。无论如何,加载器的完整事件(onLoad)没有为imgManager对象中的加载器触发。如果我在主类中复制相同的代码并要求它从内部触发相同的事件,它可以正常工作。这是我的代码:

public class ImageScroller extends Sprite
{
    public function ImageScroller()
    {
        var imgMan:ImageManager = new ImageManager();
        var v:Vector.<String> = new Vector.<String>();
        v[0] = "../assets/apache_pb.gif";

        imgMan.LoadImages(v);

        addChild(imgMan.loadedImages[0]);
    }

}

public class ImageManager
{
    public var _loader:Loader;
    private var _urlRequest:URLRequest;
    private var _loadedImages:Vector.<Bitmap>;

    public var bo:Boolean = false;

    public function ImageManager()
    {
        _loader = new Loader();

        _loadedImages = new Vector.<Bitmap>();
    }

    public function LoadImages(v:Vector.<String>):void
    {

        for(var i:int = 0; i < v.length;i++)
        {
            _loader.load(new URLRequest(v[i]));
            _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad);
        }

    }

    private function onLoad(e:Event):void
    {
        bo = true;
        var bmp:Bitmap = (Bitmap)(e.target.content);
        _loadedImages[0] = bmp;
    }

    public function get loadedImages():Vector.<Bitmap>
    {
        return _loadedImages;
    }
}

}

1 个答案:

答案 0 :(得分:1)

我重写了您的代码并相信以下是解决您问题的方法:

Main.as:

package
{
    import flash.display.Sprite;

    public class Main extends Sprite
    {
        public function Main()
        {
            init();

        }// end function

        private function init():void
        {
            var imageScroller:ImageScroller = new ImageScroller("images/image1.jpg",
                                                                "images/image2.jpg",
                                                                "images/image3.jpg");
            addChild(imageScroller);

        }// end function

    }// end class

}// end package

ImageScroller.as

package
{
    import flash.display.Sprite;
    import flash.events.Event;

    public class ImageScroller extends Sprite
    {
        private var _urls:Array;
        private var _imageManager:ImageManager;

        public function ImageScroller(...urls:Array)
        {
            _urls = urls;

            init();

        }// end function

        private function init():void
        {
            _imageManager = new ImageManager();
            _imageManager.load(_urls);
            _imageManager.addEventListener(Event.COMPLETE, onImageManagerComplete);

        }// end function

        private function onImageManagerComplete(e:Event):void
        {
            addChild(_imageManager.bitmaps[0]);

        }// end function

    }// end class

}// end package

ImageManager.as

package
{   
    import flash.display.Bitmap;
    import flash.display.Loader;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.net.URLRequest;

    public class ImageManager extends EventDispatcher
    {
        private var _urls:Array;
        private var _bitmaps:Vector.<Bitmap>;
        private var _loadedBitmapCount:int;

        public function get bitmaps():Vector.<Bitmap>     
        {       
            return _bitmaps;  

        } // end function

        public function ImageManager()     
        {
            init();

        }// end function 

        public function load(urls:Array):void   
        {
            for each(var url:* in urls)
            {
                if(!(url is String))
                throw new ArgumentError("Arguments must be of type String");

            }// end for

            _urls = urls;

            for(var i:int = 0; i < _urls.length; i++)  
            {    
                var loader:Loader = new Loader();
                loader.load(new URLRequest(_urls[i]));     
                loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete);    

            }  // end for 

        } // end function

        private function init():void
        {
            _bitmaps = new Vector.<Bitmap>();

        }// end function

        private function onLoaderComplete(e:Event):void 
        {   
            if(++_loadedBitmapCount >= _urls.length)
            {
                dispatchEvent(new Event(Event.COMPLETE));

            }// end if

            var bitmap:Bitmap = (Bitmap)(e.target.content); 
            bitmaps.push(bitmap);

        }// end function

    }// end class

}// end package

<强> [UPDATE]

您遇到的问题是您在加载图像之前尝试访问它们。

imgMan.LoadImages(v);   
addChild(imgMan.loadedImages[0]);

您需要的是一个事件监听器,它会监听您的ImageManager对象在加载所有图像时调度事件。为此,我首先将您的ImageManager课程从Object更改为EventDispatcher

public class ImageManager extends EventDispatcher

现在ImageManager有两种方法来分派事件并监听它们,分别是dispatchEvent()addEventListener()方法。

接下来,我更改了代码,以便在事件侦听器调用onLoaderComplete对象时,条件将测试以查看每次调用loader事件处理程序时加载的所有图像。这是在_loadedBitmapCount integar属性的帮助下完成的,该属性在每次调用时递增,然后根据_urls数组属性的length属性的长度测试其值。满足条件后,ImageManager EventDispatcher对象将调用其dispatchEvent()方法并调度Event.COMPLETE事件对象。

public function load(urls:Array):void   
{
    // ...

    for(var i:int = 0; i < _urls.length; i++)  
    {    
        var loader:Loader = new Loader();
        loader.load(new URLRequest(_urls[i]));     
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete);    

    }  // end for 

} // end function

//...

private function onLoaderComplete(e:Event):void 
{   
    if(++_loadedBitmapCount >= _urls.length)
    {
        dispatchEvent(new Event(Event.COMPLETE));

    }// end if

}// end function

最后,我通过添加一个事件侦听器来更改ImageScroller类中的代码,该事件侦听器侦听ImageManager对象以调度Event.COMPLETE事件对象。当发生这种情况并调用onImageManagerComplete()事件处理程序时,现在可以访问已加载的图像,因为现在它们已经被加载了。

private function init():void
{
    _imageManager = new ImageManager();
    _imageManager.load(_urls);
    _imageManager.addEventListener(Event.COMPLETE, onImageManagerComplete);

}// end function

private function onImageManagerComplete(e:Event):void
{
    addChild(_imageManager.bitmaps[0]);

}// end function

如果您有任何不明白或想要问我的事情,请在此答案中添加评论。