【问题标题】:Flex conditional compilation of MXML?Flex的MXML条件编译?
【发布时间】:2011-09-10 22:13:57
【问题描述】:

在 Flex 中,现在可以使用 -define 编译器选项来完成各种很酷的事情。 在我的程序中,我使用的选项是我的一些代码被这样的块排除:

CONFIG::FACEBOOK{
   //Some code
}

而且效果很好。

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

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

【问题讨论】:

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


    【解决方案1】:

    我的解决方案是添加一些标签,以帮助注释掉某些构建中不必要的 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
    

    【讨论】:

      【解决方案2】:

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

      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}"/>
      

      这将确保组件不会添加到显示列表中,因此也不会被测量。如果您只使用可见属性,组件的尺寸仍然会被考虑在内,因此会留下“空白”空间。

      【讨论】:

      • 只写&lt;namespace:component visible="CONFIG::Debug" includeInLayout="CONFIG::Debug"/&gt;不行吗?
      • 它可能没有测试过。但我希望它评估CONFIG::DEBUG 常量,而是将其作为String 传递给属性。如果将它们包裹在花括号中,它可能会起作用。为了方便起见,我使用了静态常量类。如果更改名称,您可以轻松重构那些,CONFIG::* 常量需要手动替换,如果您忘记了,您不会收到正确的错误消息,因此更容易出错。
      • 好点。我也走了你的路,因为我还必须在普通的 AS 类中引用它们,而且我的 IDE (FlashDevelop) 不提供 CONFIG::* 常量的代码完成。
      • FlashBuilder 也没有编译时常量的代码完成功能。它们很有用,但有时使用起来很痛苦。
      • 我不知道是否还有人使用这个/关心,但维护一个较旧的项目,我刚刚发现这个工作:&lt;s:HSlider visible="{CONFIG::mac &amp;amp;&amp;amp; AppModel.useFeelAPI}" ...。请注意 &amp;amp;&amp;amp;&amp;&amp; 运算符的丑陋用法 - 没有这个 XML 解析器。
      【解决方案3】:

      根据此评论编辑回复:

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

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

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

      弹性 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

      弹性 4

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

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

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

      2. 实现一个模板组件,该组件准确定义允许作为子组件的类型,并且仅为当前构建类型初始化适当的子组件。
        下面是一个这样创建模板组件的例子:Using IDeferredInstance in a template component.

      希望这能给你一些思考,希望它不会太复杂:)


      原答案:

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

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

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

      有了更多信息,我们或许能够找到可接受的替代方案:)

      【讨论】:

      • 很抱歉回到这个帖子很慢。我的意图是让一些界面元素(按钮等)在某些构建中被省略并包含在其他构建中。我目前的解决方法是简单地将组件的可见属性设置为编译器定义的布尔常量——它很粗糙,但它可以工作。有什么更好的办法吗?>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-23
      • 2010-10-20
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      相关资源
      最近更新 更多