开发者

AS3 event handler in child object is not firing

Maybe I missed some point along the way when learning AS3 and event handling. Anyways, the loader's complete event (onLoad) is not firing for the loader within the imgManager object. If I copy the same code in the main class and ask it to fire the same event from within itself it works fine. Here is my code:

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;
    }
}

}


I rewrote your code and believe the following is the solution to you problem:

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]

The problem you where having was that you tried to access the loaded images before they were loaded.

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

What you needed was an event listener that would listen for your ImageManager object to dispatch an event when it had loaded all the images. To do this, I first changed your ImageManager class from an Object to an EventDispatcher.

public class ImageManager extends EventDispatcher

Now the ImageManager has the two methods needed to dispatch an event and listen for it which are respectively the dispatchEvent() and addEventListener() methods.

Next I changed the code so that condition would test to see if all the images where loaded on each call to the onLoaderComplete event handler when the loader objects when the event listeners call it. This was done with the help of the _loadedBitmapCount integar property that incremented on each call then tested its value against the length of the _urls array property's length property. When the condition was met, the ImageManager EventDispatcher object would call its dispatchEvent() method and dispatch an Event.COMPLETE event object.

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

Finally I changed the code in the ImageScroller class by adding an event listener that listened for the ImageManager object to dispatch the Event.COMPLETE event object. When this would happen and the onImageManagerComplete() event handler was called, now the loaded images were accessible, because now they had been infact loaded.

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

If there is anything you didn't understand or want to ask me about, just add a comment to this answer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜