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?

4 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.

Leave a Reply