R – Using a composite MXML component from ActionScript

actionscriptairapache-flexmxml

I'm trying componentize one of the pieces of UI in an AIR application that I'm developing in Flex. In this example, I want to display file information on a single line (which has an icon, some text/link and the size).

My code looks like this (component is called FileDisplay):

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
        <![CDATA[
            public function set iconType(source:String):void {
                this.ficon.source = source;
            }

            public function set fileName(name:String):void {
                this.fname.htmlText = name;
            }

            public function set fileSize(size:String):void {
                this.fsize.text = size; 
            }
        ]]>
    </mx:Script>
    <mx:Image id="ficon" />
    <mx:Label id="fname" left="20" right="30" text="Filename" />
    <mx:Label id="fsize" right="0" text="0 K" />
</mx:Canvas>

When I'm using this component in my main application, the actionscript looks like:

for each (var file:XML in result.files) {
    var fd:FileDisplay = new FileDisplay();
    fd.fileName = '<a href="blah">'+file.name+'</a>';
    fd.iconType = getFileTypeIcon(file.name);
    fd.fileSize = getFileSizeString(file.size);

    this.file_list.addChild(fd);
}

However, when I do this, I get an error: Error #1009: Cannot access a property or method of a null object reference. This is because the child components of the FileDisplay are null (or at least they show up that way in the debugger).

Does anyone know if there's a way around this? Am I supposed to be waiting for events indicating the child components were created? Is there a more common pattern that solves this problem?

For now I can manually do everything in ActionScript in my main app (create a Canvas and add children to it) but I would appreciate any insight on how to separate the code more cleanly.

Best Answer

Bindable to the rescue:

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
        <![CDATA[
                [Bindable]
                public var iconType:String;
                [Bindable]
                public var fileName:String = "Filename";
                [Bindable]
                public var fileSize:String = "0 K";
        ]]>
    </mx:Script>
    <mx:Image id="ficon" source="{iconType}"/>
    <mx:Label id="fname" left="20" right="30" text="{fileName}" />
    <mx:Label id="fsize" right="0" text="{fileSize}" />
</mx:Canvas>

the values will be automatically updated when the components are created.