Flex Initialize and the Hassles of Changing State
One of the features of Adobe Flex that gives it so much power is the ability to build proper MVC-architected projects. You can build your views with MXML, usually with some basic scripting, and keep the real code and data separate. And part of that power is the ability to create different view states for your applications. A common scenario for using different view states might be: a loading state, a main menu state, and the main application UI state. When you change states, you often need some code to fire off and do its thing – whether that be (re)initializing data, making remote procedure calls, starting an animation, starting a Timer, or any of a million other things. One of the most common ways people achieve this is by adding a listener to the initialize event in their view components. This works great because initialization is called after all the behind-the-scenes work of changing states is done in Flex.
But what happens when you go back and forth between states? For instance, let’s say you build a game that returns you to the main menu state after a game-over scenario. If you try this, you’ll find a nasty surprise that can be a real headache to track down; the initialize event listeners work just fine the first time, but never again afterwards. To put this in terms of our example, the game starts just fine the first time, but when you return to the main menu and then start a new game, nothing happens. Or worse, the game is still showing the “Game Over” screen!
Under normal circumstances, Flex initializes your view components the first time they are accessed. After that, Flex has already done the construction, attachment and initialization and has kept all of that in memory, so there is no need for it to re-initialize when you return to a state.
To get around this, I use the render event combined with a stateChanged Boolean. I use the Model Locator design pattern as described in the Adobe Cairngorm framework. It’s a life-saver in Flex – I don’t know how I lived without it. A quick summation of the ModelLocator: it’s a singleton class that gives you universal access to your application data.
The easiest way to demonstrate this is with an example. Here are the basic features:
- For each view, add a
renderevent listener. - Use a Boolean (called
stateChangedin this example) via the ModelLocator to ensure that the code in step 1 is called only once each time the state is viewed. This is needed because therenderevent is called every time the view is redrawn, which is quite often! - The Application code (i.e. the code attached to the
ApplicationMXML [in Main.as in this example]) has acurrentStateChangeevent listener that toggles thestateChangedBoolean.
And here is the demo app. Right-click on the application and then click “View Source” to download the source code. Notice how the “initialization” code for each view is called every time the view is changed. This is because we use the render event instead of the initialize event. This also allows you to easily fire off these event handlers any time by simply changing stateChanged to true.
If you use FlashDevelop, you can download this FlashDevelop version of the example with the project file (built with FlashDevelop 3.0.0 Beta 7).
July 16th, 2009 at 10:48 pm
Could you publish your source? I’m intrigued by this render event because I’m having the same issue with the initialize event and cannot seem to find much information about this render event.
Thanks,
Dan
daniel.bucholtz@manpower.com
July 17th, 2009 at 7:02 am
Hi Dan,
You can grab the source by right-clicking (ctrl-clicking on a Mac) the Flex app and clicking “View Source”.