为什么视觉元素不会显示在从另一个自定义组件扩展的自定义组件内

发布于 2024-12-03 06:45:21 字数 1261 浏览 1 评论 0原文

我创建了一个自定义 MXML 组件 TurboContent,它扩展了 NavigatorContent 类:

<s:NavigatorContent xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx">

<fx:Metadata>
[DefaultProperty("mxmlContentFactory")]
</Fx:Metadata>

<s:Group id="midWrapper">
    <s:Button id="btnAdd" />
</s:Group>
<s:Group id="rightWrapper" >
    <s:DataGrid id="dgdSelect" >
        <s:columns>
            <s:ArrayList>
                <s:GridColumn headerText="Yo"></s:GridColumn>
            </s:ArrayList>
        </s:columns>
    </s:DataGrid>
    <s:Button id="btnRemove" />
    <s:Button id="btnClear" />
</s:Group>
</s:NavigatorContent>

我试图扩展该自定义组件,但是当我将显示元素添加到第二个扩展组件时,它们的元素永远不会被看到。例如:(第一个自定义组件位于 comp 包中)

<comp:TurboContent xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        xmlns:comp="comp.*">

<s:Button id="myButton"/>

</comp:TurboContent>

在这种情况下,“myButton”组件永远不会显示,但基本组件的所有元素都会显示(3 个按钮和一个数据网格)。

I created a custom MXML component, TurboContent, that extends the NavigatorContent class:

<s:NavigatorContent xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx">

<fx:Metadata>
[DefaultProperty("mxmlContentFactory")]
</Fx:Metadata>

<s:Group id="midWrapper">
    <s:Button id="btnAdd" />
</s:Group>
<s:Group id="rightWrapper" >
    <s:DataGrid id="dgdSelect" >
        <s:columns>
            <s:ArrayList>
                <s:GridColumn headerText="Yo"></s:GridColumn>
            </s:ArrayList>
        </s:columns>
    </s:DataGrid>
    <s:Button id="btnRemove" />
    <s:Button id="btnClear" />
</s:Group>
</s:NavigatorContent>

I am trying to extend that custom component but when I add display elements to the second extended componet they elements are never seen. For instance: (The first custom component is in the comp package)

<comp:TurboContent xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        xmlns:comp="comp.*">

<s:Button id="myButton"/>

</comp:TurboContent>

In this case, the 'myButton' component never shows up, but all the elements of the base component do (3 buttons and a datagrid).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

计㈡愣 2024-12-10 06:45:21

我很想了解您想要实现什么目标?

从代码片段来看,您似乎正在尝试编写一个新视图,该视图在视觉上继承了 TurboContent 组件并向其添加另一个按钮。

真正发生的事情是 NavigatorContent 扩展了 SkinnableContainer。 SkinnableContainer 有一个默认属性 mxmlContentFactory,一旦初始化就无法更改或替换,也不能在其上添加内容,除非您使用 ActionScript 执行此操作:

mxmlContentFactory = null; // 或者一些 IDeferredInstance

但是这样你的视觉继承方法就不是视觉继承,而是内容替换。

基类已经对其进行了初始化,因此子类无法对其进行修改。

I'm curious to understand what you're trying to achieve?

From the pieces of code it seems you're trying to compose a new view which visually inherits the TurboContent-component and adds another button to it.

What happens really under the hood is that the NavigatorContent extends SkinnableContainer. SkinnableContainer has as a default property mxmlContentFactory, which once initialized can not be changed or substituted, or add stuff on top of it, unless you do that with ActionScript:

mxmlContentFactory = null; // or some IDeferredInstance

But then your approach of visual inheritance won't be visual inheritance, but content substitution.

The base class already has initialized it, so the subclasses can't do modifications to it.

笔芯 2024-12-10 06:45:21

据我所知,直接在 MXML 中定义组件的模式(正如您在 FIAW 系列中所引用的那样)不允许在容器的显示列表中直观地插入子组件。问题之一是 mxmlContent (通常由皮肤控制)是在组件中静态定义的,并且似乎无法在 MXML 内使用 contentGroup直接组件。

为了更好的控制,以及我认为更严格的 MVC 模式实现(Flex 4 作为一个框架实现),请尝试将视觉布局分离到 MXML 皮肤中,并在 AS3 中定义组件。

从我对您的组件的了解来看,我无法真正判断您想要向将实例化它的容器公开组件的哪些属性。我至少会在这里给出一个示例,说明如何将信息从组件传递到皮肤。

我对 MX 组件表示歉意,但我只有 Flex 4.1,并且我想确保程序编译正常。更换 Spark 版本对您来说应该不会太难。

示例组件 (TurboContentAS.as)

package components {

  import mx.controls.DataGrid;
  import spark.components.NavigatorContent;

  public class TurboContentAS extends NavigatorContent {

    public function TurboContentAS() {
      super();
    }

    // Skin Parts that constitute the necessary parts of the component
    [SkinPart(required="true")]
    public var dgdSelect:DataGrid;  //just an example

    // property you want to expose to the instantiating object
    [Bindable]
    public var firstColumnHeader:String = "default header";

  }
}

示例皮肤 (TurboContentSkin.mxml)

<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        alpha.disabled="0.5" >

    <fx:Metadata>[HostComponent("components.TurboContentAS")]</fx:Metadata>

    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>

    <!-- this is where the children that you add later go-->
    <s:Group id="contentGroup" left="0" right="0" top="100" bottom="0" minWidth="0" minHeight="0">
        <s:layout>
            <s:BasicLayout/>
        </s:layout>
    </s:Group>
    <s:Group id="midWrapper">
        <s:Button id="btnAdd" label="Add" />
    </s:Group>
    <s:Group id="rightWrapper" left="200">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
        <mx:DataGrid id="dgdSelect">
            <mx:columns>
                <fx:Array>
      <!-- This will bind to the publicly exposed property in the component definition -->
                    <mx:DataGridColumn  headerText="{hostComponent.firstColumnHeader}"/>
                </fx:Array>
            </mx:columns>
        </mx:DataGrid>
        <s:Button id="btnRemove" label="Remove"/>
        <s:Button id="btnClear" label="Clear"/>
    </s:Group>
</s:Skin>

示例实例化

<components:TurboContentAS skinClass="skins.TurboContentSkin" firstColumnHeader="myHeader">
        <s:Button label="myButton"/>
    </components:TurboContentAS>

From what I can tell, the pattern of defining a component directly in MXML (as you referenced was done in the FIAW series) disallows the ability to then visually insert children in the container's display list. One of the problems is that the mxmlContent (which normally a skin would control) is statically defined in the component and it doesn't seem like one can use contentGroup inside the MXML component directly.

For better control, and what I consider a more strict implementation of the MVC pattern (which Flex 4, as a framework, implements), try separating your visual layout out into an MXML skin, and defining the component in AS3.

From what little I see of your component, I can't really make a judgment as to what properties of the component you want to expose to the container that will instantiate it. I'll at least give an example here of how one can pass info from the component to the skin.

I apologize for the MX components, but I only have Flex 4.1, and I wanted to make sure the program compiled fine. It shouldn't be too hard for you to swap in the spark versions.

Example Component (TurboContentAS.as)

package components {

  import mx.controls.DataGrid;
  import spark.components.NavigatorContent;

  public class TurboContentAS extends NavigatorContent {

    public function TurboContentAS() {
      super();
    }

    // Skin Parts that constitute the necessary parts of the component
    [SkinPart(required="true")]
    public var dgdSelect:DataGrid;  //just an example

    // property you want to expose to the instantiating object
    [Bindable]
    public var firstColumnHeader:String = "default header";

  }
}

Example Skin (TurboContentSkin.mxml)

<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        alpha.disabled="0.5" >

    <fx:Metadata>[HostComponent("components.TurboContentAS")]</fx:Metadata>

    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>

    <!-- this is where the children that you add later go-->
    <s:Group id="contentGroup" left="0" right="0" top="100" bottom="0" minWidth="0" minHeight="0">
        <s:layout>
            <s:BasicLayout/>
        </s:layout>
    </s:Group>
    <s:Group id="midWrapper">
        <s:Button id="btnAdd" label="Add" />
    </s:Group>
    <s:Group id="rightWrapper" left="200">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
        <mx:DataGrid id="dgdSelect">
            <mx:columns>
                <fx:Array>
      <!-- This will bind to the publicly exposed property in the component definition -->
                    <mx:DataGridColumn  headerText="{hostComponent.firstColumnHeader}"/>
                </fx:Array>
            </mx:columns>
        </mx:DataGrid>
        <s:Button id="btnRemove" label="Remove"/>
        <s:Button id="btnClear" label="Clear"/>
    </s:Group>
</s:Skin>

Example Instantiation

<components:TurboContentAS skinClass="skins.TurboContentSkin" firstColumnHeader="myHeader">
        <s:Button label="myButton"/>
    </components:TurboContentAS>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文