How to get rid of mx:Script blocks in your MXML

UPDATE: Okay, so maybe I just wasn’t really paying attention when I’ve googled this in the past, or maybe I just know more about Flex now and I better understand what’s being discussed in the comments… but there’s a blog post about code-behind that draws exactly the distinction I outline below and in the comments, some of the Flash/Flex gurus go through the pro’s and con’s. It’s reassuring, at least!

I know, not a very clever title, but I want this post to be easily googled as I would have been elated to get this information 2 years ago when I started using Flex. If anyone know where I could find these details elsewhere, please let me know, as this is exactly the technique I’ve wanted for a long time.

There’s a debate in the Flex community about how AS3 code should be mixed with MXML. There’s a code-behind camp that suggests first creating a base class containing your AS3 code (in a .as file) which your MXML code then extends. This has all sorts of drawbacks, like having to declare all instances you want the AS3 code to access in the base class, which kinda defeats the whole purpose of separating the MXML and AS3! Then there’s the code-in-front camp that suggests having your AS3 code inherit from your MXML class. Same issues appear, though, just from a different direction.

And finally, there’s the more common approach of just using an ugly <mx:Script/> block in your MXML, which is ugly because AS3 code has to first be wrapped in a CDATA block because of the special reserved characters used (angle brackets, double-quotes) and things like “Organize Imports” doesn’t work. The end result is a very ugly chunk of non-declarative code in the middle of nice declarative XML.

Of course, some may argue that means you should just probably slice up your code along MVC lines and then you’ll have a minimal amount of code in your MXML. Sure, but the reality is that it’s never that straightforward, and besides, even with a proper amount of code I’d like to have the automatic import organizing.

And I almost forgot… when you’re working in a team situation it’s likely that the MXML and the underlying AS3 are developed by different individuals (designer and developer, respectively). Sure, the merging won’t be too heinous with the script block, but it would still be required (this is another argument for code-behind/in-front).

So today, entirely by accident, I found the solution. If you include an AS file from exactly one other file (either an AS or MXML file), the Flex Builder editor will treat that included AS file as if it was actually in that file in regards to auto-complete. In other words, if you hit CTRL+SPACE while working in the include file you’ll get the context-appropriate auto-complete pop-up as if the file was already included where you used the include directive. If you refer to the included file from two different places in your code, then it won’t work (you get whatever is common between the locations).

Oh yeah, and organize imports works perfectly.

So, now in your MXML files you can just do this:

<mx:Script source="my-source-code.as" />

And put all your AS3 code there, neatly tucked away from all your MXML. Nice. All you gotta do is come up with a naming scheme to keep your AS and MXML files grouped (for your convenience only). The MXML compiler actually produces an AS file with the same name as the MXML file, so you can’t use that. But you can use a clever variation (that doesn’t appear to break anything). The pattern I’m using right now is this:

MyViewComponent.mxml
MyViewComponent.mxml.as

Cool, huh? It almost seems too good to be true. Am I missing something?

9 Comments so far

  1. Patrick on August 30th, 2008

    It does seem to good to be true. Coming from more of a layman’s perspective, it seems like a simple code importing like you’d see in C . Seems like it should work, no?

  2. Troy on August 30th, 2008

    You’re right, it is just a plain old text import, not a distinct compilation unit. The cool (and unexpected) discovery is the fact that the Flex Builder editor considers the import and does the appropriate context auto-complete.

  3. ryan miller on August 31st, 2008

    yes, but now you’ve doubled the amount of FILES in your project, which I would find annoying. I’ve never even considered the script block in my MXML to be a big problem. Maybe because I’ve always used some kind of MVC framework, it’s never gotten out of control. Also, if your script block is getting huge, that’s a good indicator that you need to break up your MXML into sub-components.

  4. Troy on September 1st, 2008

    Doubling the amount of files is not a big deal because that’s the simplest granularity to work with version control at. If you’re working solo, then yes, it can be unnecessary, but in a team environment it wouldn’t be too much of a burden.

    And even with good MVC practices, you can still have scenarios where you have plenty of declarative MXML and plenty of imperative AS3… for those situations, this can be useful.

  5. Tony Fendall on December 17th, 2008

    I think the one thing people miss in these discussions, is the advantages of having related bits code close together.

    I personally like the fact that my components and the code which directly interfaces with those components, are both in the same file. It makes it easy to develop without having to switch back and forth between multiple files as I go

  6. Troy on December 23rd, 2008

    I like the convenience of having the AS and MXML in the same file, but don’t like some of the artifacts — most of them faults of the IDE.

    There’s also the argument that strictly speaking, mark-up (declarative) and code (imperative) should be distinct units.

  7. Troy on December 23rd, 2008

    Odd… in a recent project, this failed to work for me. Perhaps the Flex IDE gets confused at a certain scale of project? In test projects, the aforementioned splitting and importing worked like a charm (code-hinting, etc.), but in a recent larger-scale project it didn’t work at all. Hurumph!

  8. Rob on February 10th, 2009

    Thank you! This is exactly what I was looking for, and you are right about this topic being one that isn’t really google friendly!

    I haven’t actually tried this yet, but as I read this I’m wondering what the actual code block inside of the mxml.as file is…is it a package?

  9. Troy on February 10th, 2009

    The contents of the mxml.as file are a cut-n-paste of what you’d normally have between the blocks.

Leave a Reply