Are you back? Good. Did the other two posts make sense? If not, you can stop reading, because this post is about the hairy details that those simple posts overlooked.
Still with me? Great! Now for the exceptions to the rules.
UIComponent is special
After reading the first two parts, you might be thinking to yourself: “I get it. UIComponent must have a property called
children, and that’s how the child tags get added to UIComponent”. Good guess, but unfortunately, UIComponent is treated as a special case.
One reason is historical. Flex 1.0 and 1.5 didn’t have the concept of default property. There are other, real reasons why it would be hard to deal with the children of UIComponent in the same way as other tags. For starters, the initialization code for UIComponents is very complex. To get a sense of what it looks like, turn on the
-keep flag on the compiler and look at the ActionScript code that is generated. Another reason is faceless components, which are not actually children of the UIComponent tag, which brings me to….
Faceless components are special
Exception 3 — Faceless components can only go at the root level of a document.
As far as I can tell, these two exceptions are here only for historical reasons. They are annoying to language purists, but they haven’t gotten in the way of people doing actual work, so we haven’t been able to justify the work it would take to make this consistent with the rest of the language. Let me explain.
A so-called faceless component is one that doesn’t derive from UIComponent. Some examples are the
Parallel tag and the
HTTPService tag, etc.
Anyway, the only way to create a faceless component is by subclassing an existing class using pure ActionScript. Usually, that’s ok. For example, you wouldn’t need MXML to create a subclass of HTTPService. There are a few times when it might make sense to use MXML to subclass an ActionScript class. For example, you might want to define a new effect class by putting a bunch of effects in parallel via MXML. Unfortunately, you can’t do that. This is the gist of exception 2.
<!-- This file will not compile --> <mx:Parallel xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Fade alphaFrom="0" alphaTo="1"/> <mx:Move xBy="50" /> </mx:Parallel>
Exception 3 is about how faceless componets are used within MXML files. You can only put faceless components at the top level of an MXML file. There is no good reason for this, but then again, there is no good reason to put a faceless component anywhere other than the top level of your file.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:HBox > <!-- this won't compile --> <mx:HTTPService id="foo" /> <mx:/HBox/> </mx:Application >
Some tags are even more special
There are some tags which aren’t components at all (like the
Script tag.. notice that there is no ActionScript class called
Script) that are hard-coded into the compiler. The full list of these can be found here.
Unfortunately, each one has slightly different rules.
Allowed anywhere that UIComponent is allowed:
- <Script> (surprising, but true)
Allowed only at the top level:
Only allowed in factory properties (like itemRenderer)
Only allowed inside of WebService:
Only allowed inside of RemoteObject:
Only allowed inside of method:
- <mx:arguments> (notice that this is the only case in the whole language where a lowercase tag is inside another lowercase tag!)
Only allowed inside of HTTPService and operation:
There are other quirks, but in general, these rules don’t feel as awkward as they do when I write them down like this. You would never think to put an
arguments tag in anything other than a
method, and you wouldn’t put a
method on anything other than
Sometimes, you can use tags that don’t exist
The exception above is pretty self-explanatory. It is what it is.
You probably won’t need to know any of these above exceptions to do your work on an ongoing basis, but sometimes it helps to understand the minute details behind the technology you use. Hope you found it interesting!