如何使用 mxml 继承状态? [英] How to inherit states with mxml?

查看:25
本文介绍了如何使用 mxml 继承状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下名为 AdvancedPanel 的面板组件,带有 controlBarContent:

I have the following panel component called AdvancedPanel with controlBarContent:

<!-- AdvancedPanel.mxml -->
<s:Panel>
  <s:states>
    <s:State name="normal" />
    <s:State name="edit" />
  </s:states>
  <s:controlBarContent>
    <s:Button 
      includeIn="edit"
      label="Show in edit"
      />
    <s:Button 
      label="Go to edit"
      click="{currentState='edit'}"
      />
  </s:controlBarContent>
</s:Panel>

我基于 AdvancedPanel 创建了第二个面板,名为 CustomAdvancedPanel,因为我不想重新声明 controlBarContent

I created a second panel, called CustomAdvancedPanel based on the AdvancedPanel since I don't want to redeclare the controlBarContent

<!-- CustomAdvancedPanel.mxml -->
<local:AdvancedPanel>
  <s:Button includeIn="edit" label="Extra edit button" />
</local:AdvancedPanel>

这不起作用,因为 CustomAdvancedPanel 中的编辑"状态不是根据编译器声明的.我必须重新声明 CustomAdvancedPanel.mxml 中的编辑状态,如下所示:

This doesn't work, because the 'edit' state in CustomAdvancedPanel isn't declared according to the compiler. I have to redeclare the edit state in CustomAdvancedPanel.mxml as follows:

  <!-- CustomAdvancedPanel.mxml with edit state redeclared -->
    <local:AdvancedPanel>
      <local:states>
        <s:State name="normal" />
        <s:State name="edit" />
      </local:states>
      <s:Button includeIn="edit" label="Extra edit button" />
    </local:AdvancedPanel>

在应用程序组件内使用 CustomAdvancedPanel 会显示一个带有转到编辑"按钮的空面板.但是当我点击它时,额外编辑按钮"变得可见,但 controlBar 内的在编辑中显示"按钮不可见.

Using the CustomAdvancedPanel inside an application component shows an empty panel with the "Go to edit" button. But when I click it, the "Extra edit button" becomes visible, but the "Show in edit" button inside the controlBar doesn't.

当 CustomAdvancedPanel 为空,没有重新声明的状态和额外编辑按钮"时,面板工作正常.

When the CustomAdvancedPanel is empty, without redeclared states and "Extra edit button" the panel works just fine.

我认为是因为AdvancedPanel中声明的State对象和CustomAdvancedPanel不一样,所以状态不同,即使它们同名.然而.如果没有在 mxml 中(重新)声明它们,我就无法在 CustomAdvancedPanel 中使用 AdvancedPanel 的状态.

I think it is because the State object declared in AdvancedPanel isn't the same as CustomAdvancedPanel, so the state is different, even if they have the same name. However. I can't use the states of AdvancedPanel inside CustomAdvancedPanel without (re)declare them in mxml.

有没有办法实现这种状态重用?或者有没有更好的方法来获得相同的结果?

Is there any way to achieve this kind of state-reuse? Or is there a better way to obtain the same result?

推荐答案

我建议您使用 Spark 的蒙皮架构来实现您的目标.因为皮肤状态是在宿主组件中继承的,所以您可以以 OOP 方式放置所有逻辑.但是皮肤仍然会包含重复的代码:(无论如何它比所有组件的重复代码要好.

I suggest you to use Spark's skinning architecture to obtain your goals. Because skin states are inherited in host component you can place all the logic in OOP way. But skins will still contain duplicate code :( Anyway it is better than duplicate code of all the component.

所以我们的 AdvancedPanel 将如下所示:

So our AdvancedPanel will look like the following:

package
{
    import flash.events.MouseEvent;

    import spark.components.supportClasses.ButtonBase;
    import spark.components.supportClasses.SkinnableComponent;

    [SkinState("edit")]
    [SkinState("normal")]
    public class AdvancedPanel extends SkinnableComponent
    {
        [SkinPart(required="true")]
        public var goToEditButton:ButtonBase;
        [SkinPart(required="true")]
        public var showInEditButton:ButtonBase;

        private var editMode:Boolean;

        override protected function getCurrentSkinState():String
        {
            return editMode ? "edit" : "normal";
        }

        override protected function partAdded(partName:String, instance:Object):void
        {
            super.partAdded(partName, instance);
            if (instance == goToEditButton)
                goToEditButton.addEventListener(MouseEvent.CLICK, onGoToEditButtonClick);
        }

        override protected function partRemoved(partName:String, instance:Object):void
        {
            super.partRemoved(partName, instance);
            if (instance == goToEditButton)
                goToEditButton.removeEventListener(MouseEvent.CLICK, onGoToEditButtonClick);
        }

        private function onGoToEditButtonClick(event:MouseEvent):void
        {
            editMode = true;
            invalidateSkinState();
        }
    }
}

对于 CustomAdvancedPanel:

And for CustomAdvancedPanel:

package
{
    import spark.components.supportClasses.ButtonBase;

    public class CustomAdvancedPanel extends AdvancedPanel
    {
        [SkinPart(required="true")]
        public var extraEditButton:ButtonBase;
    }
}

当然你可以从 Panel 类继承,但我让示例代码更简单.

Of course you can inherit from Panel class but I made sample code more simple.

还有皮肤:

<?xml version="1.0" encoding="utf-8"?>
<!-- AdvancedPanelSkin.mxml -->
<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">
    <fx:Metadata>
        [HostComponent("AdvancedPanel")]
    </fx:Metadata>
    <s:states>
        <s:State name="normal" />
        <s:State name="edit" />
    </s:states>
    <s:Panel left="0" right="0" top="0" bottom="0">
        <s:controlBarContent>
            <s:Button id="showInEditButton" label="Show in edit" includeIn="edit" />
            <s:Button id="goToEditButton" label="Go to edit" />
        </s:controlBarContent>
    </s:Panel>
</s:Skin>

还有:

<?xml version="1.0" encoding="utf-8"?>
<!-- CustomAdvancedPanelSkin.mxml -->
<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">
    <fx:Metadata>[HostComponent("CustomAdvancedPanel")]</fx:Metadata>
    <s:states>
        <s:State name="normal" />
        <s:State name="edit" />
    </s:states>
    <s:Panel left="0" right="0" top="0" bottom="0">
        <s:Button includeIn="edit" label="Extra edit button" id="extraEditButton" />
        <s:controlBarContent>
            <s:Button id="showInEditButton" label="Show in edit" includeIn="edit" />
            <s:Button id="goToEditButton" label="Go to edit" />
        </s:controlBarContent>
    </s:Panel>
</s:Skin>

这篇关于如何使用 mxml 继承状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆