MyComponent.mxml:
<?xml version="1.0"?>
<mx:Canvas ... >
<fx:Script>
[Bindable]
public var headingText:String = "Default Heading Text";
</fx:Script>
<s:VGroup>
<s:Label text="{headingText}" ... />
(INSTANCE MXML)
</s:VGroup>
<mx:Image ... />
</mx:Canvas>
这将使您可以这样传递headingText:
<my:MyComponent headingText="Custom Heading Text" />
你可以采用相同的方法传递其他简单值;只需声明一个公共属性,使其可绑定,然后在组件内部使用数据绑定将属性连接到其目标(或目标)即可。
对于复杂属性(比如你的INSTANCE MXML),也可以采用相同的方式实现。当你使用它时,它看起来像这样:
<my:MyComponent>
<my:thePropertyName>
<s:Label text="whatever..." ... />
<(OTHER MXML CONTENT) />
</my:thePropertyName>
<my:someOtherPropertyName>
....
</my:someOtherPropertyName>
</my:MyComponent>
如果您想了解如何实现此功能,可以查看Flex框架中spark.components.Group
组件的 mxmlContent
属性。由于源代码过长,无法在此处发布,我也找不到直接链接到源代码的在线链接。但基本思路如下(您可以在mxml文件的<fx:Script>
块中执行以下所有操作 - 您不必创建一个纯AS类来执行此操作):
[1]
将属性声明为类型Array
,并使用元数据ArrayElementType
指定您希望数组包含的类型。
[ArrayElementType("mx.core.IVisualElement")]
public function set mxmlContent(value:Array):void {
_mxmlContent = value;
}
private var _mxmlContent:Array;
[2] 您需要一些逻辑来在运行时循环遍历数组,并将数组的内容添加到组件的显示列表中。覆盖 createChildren
方法是一个不错的触发地点。以下代码松散地源自 spark Group
的 setMXMLContent()
方法实现,它并不涵盖所有可能的情况,但可以让您入门:
override protected function createChildren():void {
super.createChildren();
if( _mxmlContent == null ) return;
for (i = 0; i < _mxmlContent.length; i++) {
var elt:IVisualElement = _mxmlContent[i];
addElement(elt);
}
}
现在你的组件将拥有一个名为mxmlContent
的属性,可以使用以下语法从父级mxml组件中设置:
<my:MyComponent>
<my:mxmlContent>
... (MXML ELEMENTS HERE) ...
</my:mxmlContent>
</my:MyComponent>
你可以通过应用元数据
[DefaultProperty("mxmlContent")]
将你的新属性变成组件的
default property
。要从mxml中实现这个目标,只需要将元数据定义包装在
<fx:Metadata>
元素中即可。点击
此处查看fx:Metadata示例。
将上述内容整合起来,你会得到可以像下面这样使用的东西:
<my:MyComponent headingText="Custom Text Here">
(CUSTOM MXML CONTENT HERE)
</my:MyComponent>
编辑: 我应该在这里做一些注释:
"Halo" 组件 (例如 mx:Canvas
) 不支持上述使用方式的 addElement()
,所以你可能需要使用 addChild()
。
你应该(可能)使用 Spark 组件而不是 Halo 组件。也就是说,使用 <s:Group>
作为基础组件,而不是 <mx:Canvas>
。如果你这样做,那么你的组件将继承上面描述的 mxmlContent
属性。如果你想让你的组件拥有自己的 "content" 属性(甚至多个 "content" 属性),只需将其命名为不同的名称即可。