Flex
compiles your application into a SWF file that contains a single
application object, of type spark.components.Application or mx.core.Application.
In most cases, your application has one application object. Some
applications use the SWFLoader control to add more applications.
An application object has the following characteristics:
The file defining the application object is the first
file loaded by the application.
You can refer to the application object as mx.core.FlexGlobals.topLevelApplication from
anywhere in the application.
If you load multiple nested applications by using the SWFLoader
control, you can access the scope of each higher application in
the nesting hierarchy by using parentApplication, parentApplication.parentApplication,
and so on.
About documents
Every
MXML file used in an application is referred to as a document class.
For example, you define an MXML file named MyForm.mxml that contains
the following code:
MyForm.mxml is the document class and instances of MyForm.mxml
are referred to as documents. An MXML file that includes
the <s:Application> or <mx:Application> tag
is the document class that defines the application object. MXML
files that omit the <s:Application> or <mx:Application> tag
are custom controls.
A document has the following characteristics:
All MXML files that an application uses are document
classes, including the MXML file that includes the <s:Application> or <mx:Application> tag.
Custom ActionScript component files are document classes.
The Flex compiler cannot compile a SWF file from a file that
does not contain the <s:Application> or <mx:Application> tag.
You can access the scope of a document’s parent document
by using parentDocument, parentDocument.parentDocument,
and so on.
Flex provides a UIComponent.isDocument property
so that you can detect if any given object is a document.
Accessing document and application scopes
In
your application’s main MXML file, the file that contains the <s:Application> or <mx:Application> tag,
you can access the methods and properties of the application object
by using the this keyword. However, in custom ActionScript
and MXML components, event listeners, or external ActionScript class
files, Flex executes in the context of those components and classes,
and the this keyword refers to the current document
and not to the application object. You cannot refer to a control
or method in the application from one of these child documents without
specifying the location of the parent document.
Flex provides the following properties that you can use to access
parent documents:
mx.core.FlexGlobals.topLevelApplication
The top-level application object, regardless of where in
the document tree your object executes. This object is of type spark.components.Application
or mx.core.Application.
mx.core.UIComponent.parentDocument
The parent document of the current document. You can use parentDocument.parentDocument to
walk up the tree of multiple documents.
mx.core.UIComponent.parentApplication
The Application object in which the current object exists.
Applications can load other applications, therefore, you can access
the immediate parent application by using this property. You can
use parentApplication.parentApplication to walk
up the tree of multiple applications.
Using the mx.core.FlexGlobals.topLevelApplication property
To access properties
and methods of the top-level application object from anywhere in
your application, you can use the topLevelApplication property
of the FlexGlobals class. For example, you define an application
that contains the method, as the following code shows:
<?xml version="1.0"?>
<!-- containers\application\AppDoSomething.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:MyComps="myComponents.*">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
// Open an Alert control.
public function doSomething():void {
Alert.show("The doSomething() method was called.");
}
]]>
</fx:Script>
<!-- Include the ButtonMXML.mxml component. -->
<MyComps:ButtonMXML/>
</s:Application>
The executing SWF file for the previous example is shown below:
You can then use the FlexGlobals.topLevelApplication property
in the ButtonMXML.mxml component to reference the doSomething() method, as
the following example shows:
<?xml version="1.0"?>
<!-- containers\application\myComponents\ButtonMXML.mxml -->
<s:SkinnableContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark">
<s:layout>
<s:HorizontalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
// To refer to the members of the Application class,
// you must import mx.core.Application.
import mx.core.FlexGlobals;
]]>
</fx:Script>
<s:Button label="MXML Button"
click="FlexGlobals.topLevelApplication.doSomething();"/>
</s:SkinnableContainer>
The topLevelApplication property
is especially useful in applications that have one or more custom
MXML or ActionScript components that each use a shared set of data.
At the application level, you often store shared information and
provide utility functions that any of the components can access.
For
example, suppose that you store the user’s name at the application
level and implement a utility function, getSalutation(),
which returns the string “Hi, userName”. The following example
MyApplication.mxml file shows the application source that defines
the getSalutation() method:
<?xml version="1.0"?>
<!-- containers\application\AppSalutation.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:MyComps="myComponents.*">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
public var userName:String="SMG";
public function getSalutation():String {
return "Hi, " + userName;
}
]]>
</fx:Script>
<!-- Include the ButtonGetSalutation.mxml component. -->
<MyComps:ButtonGetSalutation/>
</s:Application>
The executing SWF file for the previous example is shown below:
To access the userName and
call the getSalutation() method in your MXML components,
you can use the topLevelApplication property, as
the following example from the MyComponent.mxml component shows:
<?xml version="1.0"?>
<!-- containers\application\myComponents\ButtonGetSalutation.mxml -->
<s:SkinnableContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
width="100%" height="100%">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
/* To refer to the members of the Application class,
you must import mx.core.Application. */
import mx.core.FlexGlobals;
]]>
</fx:Script>
<mx:Label id="myL"/>
<s:Button label="Click Me"
click="myL.text=FlexGlobals.topLevelApplication.getSalutation();"/>
</s:SkinnableContainer>
In this example, clicking
the Button control executes the getSalutation() function
to populate the Label control.
Using the parentDocument property
To access the parent document of an object,
you can use the parentDocument property.
The parent document is the object that contains the current object.
All classes that inherit from the UIComponent class have a parentDocument property.
In
the following example, the application references the custom AccChildObject.mxml
component:
The executing SWF file for the previous example is shown below:
In this example, the application
is the parent document of the AccChildObject.mxml component. The
following code from the AccChildObject.mxml component uses the parentDocument property
to define an Accordion container that is slightly smaller than the
Application container:
You use the parentDocument property
in MXML scripts to go up a level in the chain of parent documents.
You can use the parentDocument to walk this chain
by using multiple parentDocument properties, as
the following example shows:
parentDocument.parentDocument.doSomething();
The parentDocument property
of the application object is a reference to the application.
The parentDocument is
typed as Object so that you can access properties and methods on
ancestor document objects without casting.
Every UIComponent
class has an isDocument property that is set to true if that
UIComponent class is a document object, and false if
it is not.
If
a UIComponent class is a document object, it has a documentDescriptor property.
This is a reference to the descriptor at the top of the generated descriptor
tree in the generated document class.
For example, suppose
that AddressForm.mxml component creates a subclass of the Form container
to define an address form, and the MyApp.mxml component creates
two instances of it: <AddressForm id="shipping"> and <AddressForm id="billing">.
In
this example, the shipping object is a document object. Its documentDescriptor property
corresponds to the <mx:Form> tag at the top
of the AddressForm.mxml file (the definition of the component),
while its descriptor corresponds to the <AddressForm id="shipping"> tag
in MyApp.mxml file (an instance of the component).
Walking
the document chain by using the parentDocument property
is similar to walking the application chain by using the parentApplication property.
Using the parentApplication property
Applications can load other applications;
therefore, you can have a hierarchy of applications, similar to
the hierarchy of documents within each application. Every UIComponent
class has a parentApplication read-only property
that references the application object in which the object exists.
The parentApplication property of an application
object is never itself; it is either the application object into
which it was loaded, or it is null (for the application
object).
Walking the application chain by using the parentApplication property
is similar to walking the document chain by using the parentDocument property.