开发者

Flex conditional compilation of MXML?

开发者 https://www.devze.com 2023-04-03 20:05 出处:网络
In Flex it is now possible to use the -define compiler option to do all sorts of cool stuff. In my program, I am using the option such that some of my code is excluded by blocks like this:

In Flex it is now possible to use the -define compiler option to do all sorts of cool stuff. In my program, I am using the option such that some of my code is excluded by blocks like this:

CONFIG::FACEBOOK{
   //Some code
}

And this is working well.

How do I get a similar behaviour with MXML?开发者_Python百科

I want to do the same thing, but omitting/including MXML tags in this way, not blocks of AS code.


My solution is to add some tags that could help to comment out unnecessary blocks of mxml code in certain build. For example I want to add different buttons in Android and iOS builds:

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

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

Now run simple batch script which will comment out all Android specific code in the source for iOS build

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 is a command-line tool for finding and replacing strings

Now our code looks like this and is ready to be built for 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 -->

Inverse operation batch:

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


A trick I use is to create a static class that holds constants for the different builds:

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

And then I use these constants in my MXML:

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

This will make sure the component is not added to the display list and thusly not measured either. If you would only use the visible attribute the dimensions of the component are still taken into account and will therefore leave "empty" spaces.


Edited response, based on this comment:

Sorry for being slow to get back to this thread. My intention was to have some interface elements (Buttons, and the like) which were omitted in some builds and included in others. My current workaround is to simply set the visible property of the component to the compiler defined boolean constant - it's crude, but it works. Any thoughts on a better way? – Chris Kitching Sep 20 at 14:40

I think you might be able to use the deferred initialisation behaviour of flex to control which components are created and added to your parent component - it might be a little against the idea of MXML, but I think it's possible.

Here is a bit of background on manually initialising deferred components (for spark and mx components):
http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7aee.html

Flex 3

If you're using Flex 3 then you can override the createComponentsFromDescriptors() method and access the childDescriptors property to control exactly which child MXML components will be created.

The Creating deferred components article shows how you can get information about an MXML component from the descriptor. You could use this behaviour to determine which components should or shouldn't be instantiated for the current build.

Class reference for UIComponentDescriptor: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/core/UIComponentDescriptor.html

Flex 4

In Flex 4 it's a little less clear - all MXML components will be created from their descriptors (there isn't a childDescriptors property, just the mxmlContentFactory instance which will create all of the children).

Two options for controlling the display of MXML components might be:

  1. Override the createDeferredContent() method and initialise the child components with the mxmlContentFactor but remove elements from the returned array before setting the mxmlContent property (which adds them to the display list).

  2. Implement a template component that defines exactly what type of components are allowed as children, and only initialising the appropriate children for your current build type.
    Here is an example of creating a template component in this way: Using IDeferredInstance in a template component.

Hopefully that gives you something to think about, and hopefully it's not too complicated :)


Original answer:

The short answer is that you can't use conditional compilation for MXML tags. All MXML tags will be compiled into the component.

What are your goals in wanting to use conditional MXML?

Are you trying to include/exclude classes based on the compiler properties but still keep the short-hand MXML declarations? i.e. not have to define everything in actionscript.

With a bit more info we might be able to work through to an acceptable alternative :)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号