Raf
Raf

Reputation: 83

Event.Complete does not fire when loading a URL

I'm an experienced AS developer, but this is something very basic about flex that I can't figure out. In the class below, I'm not sure why the function imageLoaded would not be executed when the image loads a url. Is there a race condition happening here? The application is completely loaded by the time this object is created and setPicture is called. How can I get the Event.COMPLETE event to fire properly in this case?

The line and Log.info functions are conveniences for me, and they definitely work.

Here's my MXML definition:

<?xml version="1.0" encoding="utf-8"?>
<photo:PhotoClass xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:photo="com.xxx.widgets.photo.*">
    <mx:Image id="image"/>
</photo:PhotoClass>

Here's my actionscript:

public class PhotoClass extends Box {

    public var image : Image;

    public function PhotoClass() {
        image = new Image();
        image.addEventListener(Event.COMPLETE, imageLoaded);
    }

    private function line(txt : *) : void {
        Log.info(txt, "PhotoClass");
    }

    public function setPicture(url : String) : void {
        line("setPicture: " + url);         
        image.source = url;         
    } 

    public function imageLoaded(event : Event) : void {
        line("image loaded");
    }
}

Upvotes: 0

Views: 558

Answers (2)

Amarghosh
Amarghosh

Reputation: 59451

eventListeners won't register unless the sprite is attached to the application.

Can you give a reference? Because I believe the issue is something else.

When you declare an mxml file with PhotoClass as its root tag, you're extending the PhotoClass. The <mx:Image> tag in the mxml defines a public variable of type Image in the mxml class; and you already have a public var image:Image; in the super class. This will create a conflict - I'd expect a compile time error.

My guess is that since constructor is called first, it assigns an Image object to the public variable image. When the mxml is executed and the children are created, it assigns a new Image object to the public variable image (instead of correctly throwing an error). Now, the event listener was added to the Image instance created in the constructor, but by the time you set image.source in setProperty, it is a different object altogether. That is why it works when you move the event listener to setPicture - there you're assigning it to the new object.

Change the id of the mxml Image tag to something else and it will work even if the event listener was added from the constructor. Change the name of public var image to something else and you'll get a compile time error in PhotoClass.

Btw, what does the Image tag in the mxml do - is that for showing a different image? In that case you must change its id.

<!-- MyCanvas.mxml -->
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
  <mx:Label id="lbl"/>
</mx:Canvas>

<!-- the main application class -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*" 
   creationComplete="onCreate()" layout="vertical">
  <local:MyCanvas id="canvas1"/>
  <mx:Script>
    <![CDATA[
      public var canvas2:MyCanvas;
      public function onCreate():void
      {
        this.canvas1.lbl.text = "MyCanvas_1";
        canvas2 = new MyCanvas();
        this.addChild(canvas2);
        canvas2.addEventListener(FlexEvent.CREATION_COMPLETE, onCanvas2Created);
      }
      public function onCanvas2Created(e:FlexEvent):void
      {
        this.canvas2.lbl.text = "MyCanvas_2";
      }
    ]]>
  </mx:Script>
</mx:Application>

Upvotes: 3

Raf
Raf

Reputation: 83

I figured it out...

eventListeners won't register unless the sprite is attached to the application. The eventListener in this case was being added in the constructor, before the sprite was added to its parent class. I moved image.addEventListener to setPicture and it worked.

Upvotes: 2

Related Questions