Learned something new from Ted today
Read original post by Ted here
Flex is an event driven programming model and everything happens due to an event. Looking at the MXML code can confuse most of the developers unless they haven’t looked at the internal class of flex components. If we were to compare Flex, HTML and FLASH in terms of component instantiation.
- HTML instantiates top to bottom
- Flash executes across frames starting at Frame zero.
- Flex on the other had is a bit different.
When I started learning Flex, I struggled with understanding event flow and instantiation in MXML. I was puzzled because I really didn’t understand how event chain started and what happened inside a component to make it finally render on screen. Initially I used to run into numerous runtime null point exception since i used to think i could access a property of an object thinking it would have been created.
Anyhow the key is understanding the event basics and seeing the initialization and event flow, Lets look at a sample application that i have written to explain this. The structure of the application cann be understood by the following diagram.
With this Demo app there is no visual clue that you will get as an output to understand the event flow and instantiation step. its the TRACE statements that are important to explain how the event flow and instantiation happens. Below is the code for the same.
Call the following functions in a dummy APP
- preinitialize = “preinit(event)”
- initialize = “init(event)”
- creationComplete = “handlecc(event)”
1 2 3 4 5 6 7 8 9 10 11 12 | //preinit trace function private function preinit(event:FlexEvent):void{ trace(String(flash.utils.getTimer())+"ms >> preinitialize "+event.currentTarget) } //init trace function private function init(event:FlexEvent):void{ trace(String(flash.utils.getTimer())+"ms >> initialize "+event.currentTarget) } //creation complete trace function private function handlecc(event:FlexEvent):void{ trace(String(flash.utils.getTimer())+"ms >> creationComplete "+event.currentTarget) } |
Download the source here
I have also Monkey-patched the following classes
- VBox
- HBox
- Button
In all the above classes I have added a trace statement at measure() updateDisplayList() and createChildren(). you can see get these files in the source attached.
The component lifecycle happens in the following order. Note: i am not explaining what these methods do, but in what order are they executed to give you the final result.
- preInitialize()
- createChildren()
- initialize()
- measure()
- updateDisplayList()
- creationComplete()
The order of instantiation can be understood by the trace log if you compiled and debugged the demoApp
- 250ms >> preinitialize test0
- 259ms >> preinitialize test0.hbox
- 262ms >> preinitialize test0.hbox.can
- 265ms >> preinitialize test0.hbox.can.cbt1
- 266ms >> create Children – test0.hbox.can.cbt1
- 273ms >> initialize test0.hbox.can.cbt1
- 275ms >> preinitialize test0.hbox.can.cbt2
- 276ms >> create Children – test0.hbox.can.cbt2
- 277ms >> initialize test0.hbox.can.cbt2
- 278ms >> initialize test0.hbox.can
- 279ms >> create Children – test0.hbox.can
- 281ms >> preinitialize test0.hbox.vbox
- 283ms >> preinitialize test0.hbox.vbox.btn1
- 284ms >> create Children – test0.hbox.vbox.btn1
- 285ms >> initialize test0.hbox.vbox.btn1
- 287ms >> preinitialize test0.hbox.vbox.btn2
- 288ms >> create Children – test0.hbox.vbox.btn2
- 289ms >> initialize test0.hbox.vbox.btn2
- 290ms >> initialize test0.hbox.vbox
- 291ms >> create Children – test0.hbox.vbox
- 292ms >> initialize test0.hbox
- 293ms >> create Children – test0.hbox
- 294ms >> initialize test0
- 310ms >> measure – test0.hbox.can.cbt1
- 312ms >> measure – test0.hbox.can.cbt2
- 313ms >> measure – test0.hbox.vbox.btn1
- 313ms >> measure – test0.hbox.vbox.btn2
- 315ms >> measure – test0.hbox.can
- 315ms >> measure – test0.hbox.vbox
- 317ms >> measure – test0.hbox
- 344ms >> updateDisplayList – test0.hbox
- 348ms >> updateDisplayList – test0.hbox.can
- 350ms >> updateDisplayList – test0.hbox.vbox
- 351ms >> updateDisplayList – test0.hbox.can.cbt1
- 356ms >> updateDisplayList – test0.hbox.can.cbt2
- 358ms >> updateDisplayList – test0.hbox.vbox.btn1
- 359ms >> updateDisplayList – test0.hbox.vbox.btn2
- 364ms >> creationComplete test0.hbox.can.cbt1
- 365ms >> creationComplete test0.hbox.can.cbt2
- 366ms >> creationComplete test0.hbox.vbox.btn1
- 367ms >> creationComplete test0.hbox.vbox.btn2
- 368ms >> creationComplete test0.hbox.can
- 370ms >> creationComplete test0.hbox.vbox
- 371ms >> creationComplete test0.hbox
- 373ms >> creationComplete test0
Just by looking at the trace log and the application structure image you can slowly start making out a pattern (preorder traversal). preInitialize() is called first for the App then the first child(in our case only child HBOX) then its first child which is the CANVAS and finally the first child of canvas that is C BUTTON 1 after this the createChildren() and initialize() of the innermost left child is called then moving on to its sibling the preInitialize(), createChildren() and initialize() is called. This is followed till all the children have completed the preInitialize(), createChildren() and initialize() steps.
After this the measure() of all the child’s are called in a bottom up approach with left child priority.
After this the updateDisplayList() of all the children’s are aclled in a top down approach with left child priority.
Finally the creationComplete() of all the children are called again in bottom up approach with left child priority. Thus explaining why creationComplete() of the parent component is called at the very end. the more you look at the log trace the more you will understand the flow. Hope this effort of my explaining the instantiation process helped you out.
Download the source here
Tags: components, event flow, flex, lifecycle





Thanks for this very informative & useful post…
Very helpful topic :)
Sorry this post was originally written by Ted i read it and made a few changes to it…
So all the credit goes to Ted
what fine go through.
really helpful post :)