代码之家  ›  专栏  ›  技术社区  ›  W3Coder

如何将MXML子节点放入自定义Flex 4组件中?

  •  5
  • W3Coder  · 技术社区  · 15 年前

    下面是一个自定义组件的示例。它只是一个带有标题标签和闭合图像(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)”替换为多个标签、文本输入、复选框等(可能更难)。

    我发现了 this script-based method ,但我想要个清洁工 编译时 如果存在的话。有什么建议吗?

    2 回复  |  直到 15 年前
        1
  •  10
  •   Lee    15 年前

    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>
    

    这样你就可以像这样进入标题文本:

     <my:MyComponent headingText="Custom Heading Text" />
    

    对于要传入的其他简单值,可以采用相同的方法;只需声明一个公共属性,使其可绑定,然后在组件中使用数据绑定将该属性挂接到其目标(或多个目标)。

    对于复杂的属性(如实例MXML),也可以执行相同的操作。它看起来像这样,当你使用它时:

    <my:MyComponent>
      <my:thePropertyName>
         <s:Label text="whatever..." ... />
         <(OTHER MXML CONTENT) />
      </my:thePropertyName>
      <my:someOtherPropertyName>
        ....
      </my:someOtherPropertyName>
    </my:MyComponent>
    

    对于如何实现此功能的示例,可以查看 mxmlContent 财产 spark.components.Group flex框架中的组件。源代码太长,无法在这里发布,而且我似乎找不到直接指向源代码的在线链接;但基本思想是这样的(您可以在 <fx:Script> 块在mxml文件中-不必创建纯AS类即可执行此操作):

    [一] 将属性声明为类型 Array ,包含元数据 ArrayElementType 指示希望数组包含的类型。

    [ArrayElementType("mx.core.IVisualElement")]
    public function set mxmlContent(value:Array):void {
        _mxmlContent = value;
    }
    private var _mxmlContent:Array;
    

    [2]您需要一点逻辑才能在运行时循环遍历数组,并将数组的内容添加到组件的显示列表中。这个 createChildren 超驰是一个很好的触发点。下面是从 setMXMLContent() 火花法 Group . 它不包括所有可能的案例,但它会让你开始:

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

    所以现在您的组件将有一个名为 MXML含量 ,可以使用以下语法从父mxml组件设置:

    <my:MyComponent>
       <my:mxmlContent>
           ... (MXML ELEMENTS HERE) ...
       </my:mxmlContent>
    </my:MyComponent> 
    

    你可以把你的新财产 default property 通过应用元数据: [DefaultProperty("mxmlContent")] 你的组件类。要从mxml执行此操作,只需将元数据定义包装在 <fx:Metadata> 元素。 see here for example of fx:Metadata .


    把以上这些放在一起,你会得到一些你可以使用的东西:

    <my:MyComponent headingText="Custom Text Here">
       (CUSTOM MXML CONTENT HERE)
    </my:MyComponent>
    

    编辑: 我应该在这里做几个笔记:

    1. “光环”组件(如 mx:Canvas )不支持 addElement() 如上文所述,因此您可能希望使用 addChild() 相反。

    2. 你应该(可能)使用火花组件而不是光环组件。意义、用途 <s:Group> 作为你的基地而不是 <mx:Canvas> . 如果这样做,则组件将继承 MXML含量 上述属性。如果您希望组件具有自己的“内容”属性(甚至多个内容属性),只需将它们命名为不同的内容。

        2
  •  7
  •   Kamil    15 年前

    这太棒了。谢谢你的消息。

    因为我不需要太多的控制,所以我把这个解决方案简化了一点。

    容器MyComponent.mxml的代码:

    <s:Group ... >
    <fx:Script>
        <![CDATA[
    
        [Bindable]
        [ArrayElementType("mx.core.IVisualElement")]
        public var content:Array;
    
        ]]>
    </fx:Script>
    
    <s:Group width="100%" height="100%" mxmlContent="{content}" />
    

    使用方法:

    <myComponents:MyComponent
        xmlns:myComponents="myComponents.*"
    >
    
        <myComponents:content>
            <s:Label />
            <s:Label />
            <AnythingWeWant...
        </myComponents:content>
    
    </myComponents:MyComponent>
    

    希望这对任何人都有帮助。 干杯。

    推荐文章