如何将 MXML 子节点放入自定义 Flex 4 组件中?
这是自定义组件的示例。它只是一个带有标题标签和关闭图像 (X) 的框:
<?xml version="1.0"?>
<mx:Canvas ... >
<s:VGroup>
<s:Label text="(HEADING TEXT)" ... />
(INSTANCE MXML)
</s:VGroup>
<mx:Image ... />
</mx:Canvas>
在 MXML 文档中使用该组件时,我希望将“(HEADING TEXT)”替换为参数(应该很容易)以及带有多个标签、文本输入、复选框等的“(INSTANCE MXML)”(可能更难)。
我找到了这种基于脚本的方法,但我想要一个更干净的编译时解决方案(如果存在)。有什么建议吗?
Here is an example of a custom component. It is just a box with a title label and a close image (X):
<?xml version="1.0"?>
<mx:Canvas ... >
<s:VGroup>
<s:Label text="(HEADING TEXT)" ... />
(INSTANCE MXML)
</s:VGroup>
<mx:Image ... />
</mx:Canvas>
When using the component in an MXML document, I would like to have the "(HEADING TEXT)" replaced with a parameter (should be easy) as well as the "(INSTANCE MXML)" with several labels, text inputs, check boxes, etc. (maybe harder).
I have found this script-based method, but I would like a cleaner compile-time solution if one exists. Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
MyComponent.mxml:
这将让您像这样传递标题文本:
您可以对要传递的其他简单值采用相同的方法;只需声明一个公共属性,使其可绑定,然后在组件中使用数据绑定将该属性挂钩到其目的地(或多个目的地)。
您可以对复杂的属性(例如 INSTANCE MXML)执行相同的操作。当您使用它时,它看起来像这样:
有关如何实现此功能的示例,您可以查看
spark.components.Group
组件的mxmlContent
属性弹性框架。源代码太长,无法在这里发布,而且我似乎无法找到直接指向源代码的在线链接;但基本思想是这样的(您可以在 mxml 文件中的
块内执行以下所有操作 - 您不必创建一个纯 AS 类来执行此操作):[1]
将属性声明为
Array
类型,并使用元数据ArrayElementType
来指示您希望数组包含的类型。[2] 您需要一些逻辑来在运行时循环数组,并将数组的内容添加到组件的显示列表中。
createChildren
重写是触发此操作的好地方。以下内容大致源自 SparkGroup
的setMXMLContent()
方法的实现。它并没有涵盖所有可能的情况,但它会帮助您开始:所以现在您的组件将有一个名为
mxmlContent
的属性,您可以使用以下语法从父 mxml 组件中设置该属性:您可以通过应用元数据:
[DefaultProperty("mxmlContent")]
您的组件类,将新属性设置为组件的默认属性
。要从 mxml 执行此操作,只需将元数据定义包装在
元素中。 请参阅此处的 fx:Metadata 示例。将以上所有内容放在一起,您将得到可以像这样使用的东西:
编辑:我应该在这里做一些注释:
“Halo”组件(例如
mx: Canvas
)不支持上面使用的addElement()
,因此您可能需要使用addChild()
来代替。您应该(可能)使用 Spark 组件而不是 Halo 组件。意思是,使用
作为基础,而不是
。如果您这样做,那么您的组件将继承上述的mxmlContent
属性。如果您希望组件拥有自己的“内容”属性(甚至多个内容属性),只需将它们命名为不同的名称即可。MyComponent.mxml:
That will let you pass in the headingText like this:
You can follow the same approach for other simple values you want to pass in; just declare a public property, make it bindable, then within your component, use data binding to hook the property to its destination (or destinations).
You can do the same thing for complex properties (like your INSTANCE MXML). It looks like this, when you use it:
For an example of how to implement this, you can check out the
mxmlContent
property of thespark.components.Group
component in the flex framework. The source is too lengthy to post here, and I can't seem to find an online link directly to the source; but the basic idea is this (you can do all the following inside a<fx:Script>
block in an mxml file - you don't have to make a pure AS class in order to do this):[1]
declare the property as type
Array
, with metadataArrayElementType
to indicate the type you want the array to contain.[2] You'll need a little bit of logic to loop over the array at runtime, and add the array's contents to the component's display list. The
createChildren
override is a good place to trigger this. The following is derived loosely from the implementation ofsetMXMLContent()
method of sparkGroup
. It doesn't cover all possible cases, but it'll get you started:So now your component would have a property called
mxmlContent
, which you could set from a parent mxml component using the syntax:You can make your new property into the
default property
of your component, by applying the metadata:[DefaultProperty("mxmlContent")]
your component class. To do this from mxml, just wrap the metadata definition in an<fx:Metadata>
element. see here for example of fx:Metadata.put all the above together, and you'll get something you can use like this:
Edit: I should make a couple of notes here:
"Halo" components (like
mx:Canvas
) don't supportaddElement()
as used above, so you'll probably want to useaddChild()
instead.You should (probably) be using spark components instead of halo components. Meaning, use
<s:Group>
as your base instead of<mx:Canvas>
. If you do this, then your component will inherit themxmlContent
property described above. if you want your component to have its own "content" property (or even multiple content properties), just name them something different.这太棒了。感谢您提供此信息。
由于我不需要对其进行太多控制,因此我稍微简化了这个解决方案。
我们的容器 MyComponent.mxml 的代码:
和用法:
希望这对任何人都有帮助。
干杯。
This is awesome. Thanks for this info.
Since I didn't need so much control over it I've simplified this solution a little.
Code for our container MyComponent.mxml:
And usage:
Hope this helps anyone.
Cheers.