使用ActionScript中的复合MXML组件

时间:2009-08-31 23:16:46

标签: flex actionscript air mxml

我正在尝试将我在Flex中开发的AIR应用程序中的一个UI组件化。在这个例子中,我想在一行(有一个图标,一些文本/链接和大小)上显示文件信息。

我的代码看起来像这样(组件称为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>

当我在主应用程序中使用此组件时,actionscript看起来像:

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

但是,当我这样做时,我收到一个错误:错误#1009:无法访问空对象引用的属性或方法。这是因为FileDisplay的子组件为空(或者至少它们在调试器中以这种方式显示)。

有没有人知道是否有解决方法?我是否应该等待表明子组件被创建的事件?是否有更常见的模式可以解决这个问题?

现在我可以在我的主应用程序中手动执行ActionScript中的所有操作(创建一个Canvas并添加子项),但我将非常感谢如何更清晰地分离代码。

4 个答案:

答案 0 :(得分:3)

可以救援:

<?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>

创建组件时,值将自动更新。

答案 1 :(得分:1)

尚未加载子组件。

请阅读:http://livedocs.adobe.com/flex/3/html/help.html?content=ascomponents_advanced_2.html#203434

然后,当像我一样,你不理解它(并且它不可靠)时,在FileDisplay中监听FlexEvent.CREATION_COMPLETE,并在那里应用你的子组件属性。

或者更好的是,在“createChildren”函数中以编程方式创建三个子节点,并在那里应用设置。

这两种方法都假定您将filename,icontype和filesize设置为本地成员,然后将它们应用于子组件,无论您应该这样做。

答案 2 :(得分:1)

保存FileDisplay组件的父组件是什么?如果您确定该错误来自FileDisplay的子组件未被实例化的事实,那么您可能希望查看creationPolicy属性并确保它在该父组件上设置为ContainerCreationPolicy.ALL成分

=瑞恩

答案 3 :(得分:0)

除了将CreationPolicy设置为all之外,还需要通过addChild将DisplayObject添加到舞台。 FileDisplay的子项在添加之前不会创建,而是添加到舞台中。所以:

for each (var file:XML in result.files) {
   var fd:FileDisplay = new FileDisplay();
   this.file_list.addChild(fd);

   fd.fileName = '<a href="blah">'+file.name+'</a>';
   fd.iconType = getFileTypeIcon(file.name);
   fd.fileSize = getFileSizeString(file.size);    
}