Flex条件编译MXML?

时间:2011-09-10 22:13:57

标签: flex actionscript-3 mxml flex4.5 conditional-compilation

在Flex中,现在可以使用-define编译器选项来执行各种很酷的操作。 在我的程序中,我使用的选项使得我的一些代码被这样的块排除:

CONFIG::FACEBOOK{
   //Some code
}

这很好用。

如何使用MXML获得类似的行为?

我想做同样的事情,但是以这种方式省略/包括MXML标签,而不是AS代码块。

3 个答案:

答案 0 :(得分:2)

我的解决方案是添加一些标签,这些标签可以帮助在某些构建中注释掉不必要的mxml代码块。 例如,我想在Android和iOS版本中添加不同的按钮:

<!-- iOS --><!--
<s:Button id="backBtn" 
    icon="{SHOW_LIST}" 
    click="navigator.popView()"/>
--><!-- /iOS -->

<!--Android-->
<s:Button id="exitBtn" 
    label="Exit" 
    click="NativeApplication.nativeApplication.exit()"/>
<!--/Android-->

现在运行简单的批处理脚本,该脚本将注释掉iOS构建源代码中的所有Android特定代码

<强> PrepareForIos.cmd

@echo off
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "<!--Android-->" "<!-- Android --><!--"
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "<!--/Android-->" "--><!-- /Android -->"
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "<!-- iOS --><!--" "<!--iOS-->"
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "--><!-- /iOS -->" "<!--/iOS-->"
pause

FART是一个用于查找和替换字符串的命令行工具

现在我们的代码看起来像这样,并且已准备好为iOS构建:

<!--iOS-->
<s:Button id="backBtn" 
    icon="{SHOW_LIST}" 
    click="navigator.popView()"/>
<!--/iOS-->

<!-- Android --><!--
<s:Button id="exitBtn" 
    label="Exit" 
    click="NativeApplication.nativeApplication.exit()"/>
--><!-- /Android -->

反向操作批次:

<强> PrepareForAndroid.cmd

@echo off
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "<!--Android-->" "<!-- Android --><!--"
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "<!--/Android-->" "--><!-- /Android -->"
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "<!-- iOS --><!--" "<!--iOS-->"
"C:\Program Files (x86)\bin\fart.exe" -r -w -- H:\Flash\MyProject\src\* "--><!-- /iOS -->" "<!--/iOS-->"
pause

答案 1 :(得分:1)

我使用的一个技巧是创建一个静态类,它保存不同构建的常量:

package 
{
    public class MyAppConstants
    {
        CONFIG::Debug
            public static const DEBUG:Boolean = true;           
        CONFIG::Release
            public static const DEBUG:Boolean = false;
    }
}

然后我在MXML中使用这些常量:

<namespace:component visible="{MyAppConstants.DEBUG}" includeInLayout="{MyAppConstants.DEBUG}"/>

这将确保组件未添加到显示列表中,因此也未进行测量。如果您只使用visible属性,则仍会考虑组件的尺寸,因此会留下“空”空格。

答案 2 :(得分:0)

根据此评论编辑回复:

  

很抱歉回到这个帖子很慢。我的目的是有一些界面元素(按钮等)在某些版本中被省略并包含在其他版本中。我目前的解决方法是简单地将组件的visible属性设置为编译器定义的布尔常量 - 它是原始的,但它可以工作。有什么想法更好的方式? - Chris Kitching 9月20日14:40

我认为您可以使用flex的延迟初始化行为来控制创建哪些组件并将其添加到您的父组件 - 这可能与MXML的想法有点相反,但我认为这是可能的。

以下是关于手动初始化延迟组件(对于spark和mx组件)的一些背景知识:
http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7aee.html

Flex 3

如果您正在使用Flex 3,则可以覆盖createComponentsFromDescriptors()方法并访问childDescriptors属性以准确控制将创建哪些子MXML组件。

Creating deferred components文章介绍了如何从描述符中获取有关MXML组件的信息。您可以使用此行为来确定应该或不应该为当前构建实例化哪些组件。

UIComponentDescriptor的类引用: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/core/UIComponentDescriptor.html

Flex 4

在Flex 4中,它不太清楚 - 所有MXML组件都将从其描述符创建(没有childDescriptors属性,只有mxmlContentFactory实例将创建所有子项)

控制MXML组件显示的两个选项可能是:

  1. 重写createDeferredContent()方法并使用mxmlContentFactor初始化子组件,但在设置mxmlContent属性(将它们添加到显示列表)之前从返回的数组中删除元素。

  2. 实现一个模板组件,该模板组件准确定义允许哪些类型的组件作为子组件,并仅初始化当前构建类型的相应子组件。
    以下是以这种方式创建模板组件的示例:Using IDeferredInstance in a template component.

  3. 希望这给你一些思考的东西,希望它不会太复杂:)


    原始回答:

    简短的回答是你不能对MXML标签使用条件编译。 所有MXML标记都将编译到组件中。

    您希望使用条件MXML的目标是什么?

    您是否尝试根据编译器属性包含/排除类,但仍保留简短的MXML声明?即不必在actionscript中定义所有内容。

    通过更多信息,我们可以通过一个可接受的替代方案:)