So far all objects that "live" inside a Parsley Context have been defined with either MXML, XML or ActionScript as detailed in 3 Configuration and Initialization. For Flash Applications these mechanisms will usually be sufficient as it is very likely that you are able to conveniently define all managed objects in XML or ActionScript - including view elements. For Flex Application this approach is not ideal since you'll prefer to declare your components in your MXML files within the component hierarchy and not in a separate Parsley Context MXML configuration class. So we'll need a different mechanism to connect these components defined within your MXML view definitions to objects declared with Parsley configuration files. The solution Parsley offers for this use case will be described in this chapter.
To configure a Flex Component to take advantage of Parsley's IOC Container features the following steps are required:
Let's illustrate this with a simple example:
<mx:Panel
xmlns:mx="http://www.adobe.com/2006/mxml"
addedToStage="dispatchEvent(new Event('configureIOC', true));"
>
<mx:Script>
<![CDATA[
import com.bookstore.events.*;
import com.bookstore.model.*;
[Bindable]
private var user:User;
[Inject]
public var mediator:LoginMediator;
[MessageHandler]
public function handleLogin (event:LoginEvent) : void {
this.user = event.user;
}
]]>
</mx:Script>
<mx:text text="Current User: {user.name}"/>
<!-- some more components ... -->
</mx:Panel>
The metadata tags used in the example work the same way as for objects defined in Parsley configuration files.
So your Flex Component can participate in the Parsley Messaging infrastructur and request injections of objects from
the Context. To trigger the configuration of the Component we fire an event when it gets added to the stage.
The event type has to be 'configureIOC' which Parsley registers a listener for on the Flex SystemManager.
Furthermore it must be a bubbling event, thus the second parameter is true.
Note that in this example we did not follow the best practice to use a constant for the event type as it is our goal to keep the Flex Component free from imports of the Parsley API. So it will continue to work in other environments without Parsley. The event would simply be ignored then and the property values could be set directly in MXML instead of being injected by an IOC Container. You could of course define such a constant within your application classes.
If you don't mind to couple your Component to the Parsley API the framework offers a special <Configure/>
tag as an alternative:
<mx:Panel
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:parsley="http://www.spicefactory.org/parsley/flex"
>
<parsley:Configure/>
<!-- ... -->
</mx:Panel>
Due to the fact that Flex Components are connected to the IOC Container "on the fly" the lifecycle for Components
is different than for objects defined directly in the container. This affects the [PostConstruct] and
[PreDestroy] metadata tags.
Methods annotated with [PostConstruct]
For an object declared directly within a Parsley configuration file these methods get executed after the container has instantiated and configured the object. For a Flex Component that is dynamically wired it will be invoked after the container caught the configuration event dispatched by the Component and after all injections have been processed.
Methods annotated with [PreDestroy]
For an object declared directly within a Parsley configuration file these methods only get executed after the
container has been destroyed with a call to Context.destroy(). For a Flex Component that is dynamically wired it
will additionally be invoked after the Component has been removed from the stage. Of course that means that the same
instance can have multiple invocations of its PostConstruct and PreDestroy methods in case it gets removed and re-added
to the stage.
You should also be aware of some strange side effects when using the Flex PopUpManager for example.
In my tests I noticed that it has a strange way of initializing popups, often leading to a sequence
of addedToStage and removedFromStage events. In this case injections might be processed twice.
In case you are using any of the static methods of the FlexContextBuilder class, there is nothing you
need to do as the Flex View Wiring Support will implicitly be initialized by any of these methods:
FlexContextBuilder.build(BookStoreConfig); // triggers view management
In rare cases where you would build a Parsley Flex Application but not use MXML configuration at all (for example confining yourself to use XML configuration files) you'd need to explicitly add a Context to the Parsley ViewManager:
var context:Context = XmlContextBuilder.build("config.xml");
RootViewManager.addContext(context);