Chapter 3. MXML

MXML is a declarative markup language used to create the user interface and to view portions of Flex applications. As the name implies, MXML is an XML-based language. If you’re familiar with XML or even HTML, many of the basic MXML concepts we discuss in this chapter will already be familiar to you in a general sense. In this chapter, we’ll look at all the basics of working with MXML, including the syntax and structure of the language, the elements of which MXML is composed, creating interactivity in MXML, and how you can use MXML to build applications.

Understanding MXML Syntax and Structure

If you’ve ever worked with XML or HTML, the structure of MXML will be familiar to you. Even if XML and HTML are unfamiliar to you, you will likely find MXML fairly intuitive. MXML uses tags to create components such as user interface controls (buttons, menus, etc.), and to specify how those components interact with one another and with the rest of the application, including data sources. In the following sections we’ll look at how to write MXML code.

Creating MXML Documents

All MXML must appear within MXML documents, which are plain-text documents. You can use any text editor, XML editor, or IDE that can work with text or XML to write MXML, including those listed in the preceding chapter. To create a new MXML document, you can create a new text file with the .mxml file extension. If you are using Flex Builder, you can use the program’s menus to add either a new MXML application, MXML module, or MXML component. All are MXML documents, differing only in the root element added to the document (as you’ll see in this chapter).

XML encoding

Every document can and should have an XML declaration. Many IDEs and XML editors automatically add an XML declaration. Flex Builder adds an XML declaration by default using UTF-8 as the encoding. You must place the declaration as the first line of code in the MXML document, and unless you have a compelling reason to use a different encoding, you should use UTF-8 for the best compatibility:

<?xml version="1.0" encoding="utf-8"?>

Note that an XML declaration is not strictly required by the Flex compilers. However, for well-formed MXML, you should always include the XML declaration as it is recommended by the XML 1.0 specification.

Applications, modules, and components

All MXML documents can have just one root node. There are three types of MXML documents, and they are defined by the type of root node they have. The first type of MXML document is an application document. Application documents use Application nodes as the root node. All Flex applications must have one application document, and application documents are the only type of document you can compile into a Flex application. The following is an example of a basic application document that Flex Builder creates by default:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

</mx:Application>

Note

Note that the layout attribute is not strictly required, but it is shown here because this is the default tag Flex Builder creates.

There are a few items to notice about this example:

  • The Application node has matching opening and closing tags. The closing tag is prefixed by a forward slash (/). All MXML nodes must be closed as in any well-formed XML.

  • The tag name uses an mx namespace. You can identify a namespace in a tag because the tag name is prefixed with the namespace identifier followed by a colon. We’ll talk more about namespaces in the next section.

  • The Application tag in this example has two attributes, called xmlns and layout. You use attributes to set values for a node. In this case, the xmlns attribute defines the mx namespace prefix (more about this in the next section), and the layout attribute defines the way in which the contents of the document will be positioned. The layout attribute is optional (we discuss this attribute in more detail in Chapter 6). For now, you can define application documents with an absolute layout or with no explicit layout attribute value. We’ll talk more about attributes in Setting component properties” later in this chapter.

Component documents are used to define MXML components, which are encapsulated elements of your application that you can abstract and isolate into their own documents to make your applications more manageable. We’ll talk more about custom components in Chapter 9, and Chapter 19. The structure of component documents is similar to that of application documents in all respects except that the root node is not an Application tag. Rather, a component document uses an existing component as the root node (which is the superclass for the new MXML document/class). Again, we’ll discuss this in much more detail later in this chapter and later in the book. However, for illustrative purposes, here we’ll look at a simple example of a component document that is based on a standard Flex framework component called Canvas:

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

</mx:Canvas>

Note

While the preceding is a complete component document, you can't compile an application from it. All Flex applications require an application document in order to compile, and you can use instances of component documents within the application document. You’ll learn more about how to create custom components and use them in a Flex application in Chapter 9.

As you can see in this example, the structure of the document is much the same as that of the application document, but with a difference: the root node is a Canvas tag rather than an Application tag.

A module document is also remarkably similar to application and component documents, the primary difference being the root tag. A module document is used to define an MXML module, which you’ll learn more about in Chapter 9. The root tag for a module document is Module as in the following example:

<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml">

</mx:Module>

All other MXML code appears within the root node of a document. For example, if you want to add a button to an application, the document might look like this:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  <mx:Button label="Example Button"></mx:Button>
</mx:Application>

Although we haven’t yet discussed the button component, you can see quite clearly that the tag that adds the component is nested within the opening and closing tags of the root node. You’ll also see that the syntax for the tag that adds the button is similar to that of the Application tag. It uses < and > characters to demarcate the tag, and it uses the same syntax for attributes. The Button tag in this example also has an opening and closing tag. If you omitted the closing tag, the compiler would not be able to compile the application. However, in the case of the button component, you would not typically nest any tags within it. Therefore, it is sometimes convenient to be able to open and close a node with just one tag. There is a shortcut to achieve this goal. You can simply add a forward slash immediately prior to the > character of the opening tag. That means you can rewrite the preceding example in the following way:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Button label="Example Button" />
</mx:Application>

That covers the fundamentals of MXML structure. We’ll be elaborating on how to work with specific components and specialized tags throughout the remainder of the book.

Understanding namespaces

As shown in the preceding section, MXML uses something called a namespace. Simply put, a namespace is a unique grouping for elements—in this case Flex libraries. The entire Flex framework is written in ActionScript classes and a few MXML component documents that are stored in external libraries within .swc files. These external libraries contain tens if not hundreds of classes (and MXML components). Using these elements from ActionScript is not difficult. However, to use the elements from MXML you have to be able to map the library classes and MXML components to tags. You do this through manifest files and namespaces.

As shown in Chapter 2, a manifest file maps an ActionScript class to an identifier: the MXML tag name. A manifest file in and of itself would be enough to enable access to ActionScript classes and MXML components by way of MXML tags. However, the difficulty is that you need a way to ensure uniqueness of scope for the mappings. For example, the Flex framework defines a mapping called Button that points to a class called mx.controls.Button—a component that creates a simple user interface button. Yet what if you wanted to create your own class that maps to a Button identifier? This poses a problem because you cannot meaningfully have two Button identifiers within the same scope. If you did, how would the application know which button you are referencing? This highlights the utility of namespaces.

A namespace allows you to create a unique uniform resource identifier (URI) that corresponds to a particular manifest document. This namespace URI is set when the .swc file is compiled, as described in Chapter 2. You may recognize this particular URI from the MXML examples shown in the previous section. Within the MXML document you must tell Flex which namespaces you want the document to use. You can do that using the xmlns attribute. If you use the xmlns attribute by itself, it defines the default namespace for the document. Therefore, the example that follows on the next page is a valid MXML application document that adds a button component.

<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://www.adobe.com/2006/mxml" layout="absolute">
  <Button label="Example Button" />
</Application>

This example says to use the Flex framework namespace as the default namespace for the document. This means that every tag used in the document is assumed to correspond to one of the mappings in the Flex framework manifest file. Therefore, the Application tag maps to the class that corresponds to the Application identifier in the manifest file. This is perfectly valid. However, this is not the way in which MXML documents typically utilize the Flex framework namespace; an MXML document may contain tags that shouldn’t map to the Flex framework namespace by default. Therefore, it is better not to define that namespace as the default, but rather to use a namespace prefix. By convention we use the mx prefix for the Flex framework namespace. You can use a namespace prefix by following xmlns with a colon and the prefix before assigning the value, as in the following example:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  <mx:Button label="Example Button" />
</mx:Application>

This example, which is exactly the same as an earlier example, adds the mx prefix for the Flex framework namespace. That means you must then prefix all tags that are part of that namespace with the mx prefix (e.g., <mx:Button>).

By using namespace prefixes, you can create additional namespaces and utilize them within Flex applications. Each namespace can use a different prefix within the MXML document, ensuring that even if two namespaces use the same mapping identifiers, they will not be in conflict. The following example illustrates this:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                xmlns:example="http://www.example.com" layout="absolute">
  <mx:Button label="Example Button" />
  <example:Button />
</mx:Application>

This example presupposes that a valid external library is already compiled with the namespace URI of http://www.example.com and that the library’s manifest file contains a mapping identifier of Button. In this example, the application creates one button from the Flex framework and one button from the example library. We’ll see more examples of creating custom namespaces for custom libraries in Chapter 20. Although no rule states that you must use the mx prefix for the Flex framework namespace, it is the standard convention, and we use that convention in this book.

Components

Flex applications are largely composed of components, or modular elements. Technically, a component is an ActionScript class or an MXML component document that you can instantiate in an application. In some cases the class or component document has been mapped to an identifier via a manifest file, and in some cases you can merely reference the class or component document by way of the fully qualified name. There are many different types of components, but in terms of the Flex framework components, there are two basic categories: visual and non-visual. The visual components consist of the following:

  • Containers

  • User interface controls

The non-visual components consist of the following:

  • Data components

  • Utility components

Containers

Containers are types of components that can contain other components. Every application must use containers. At a minimum, the Application element itself is a container because you can place other components within it. You use containers for layout. There are containers for vertical layout, horizontal layout, grids, tiles, and all sorts of layout configurations. When you use layout containers, you place other components within them using nested tags. The following uses a VBox (a container that automatically arranges the child elements so that they are stacked vertically) to stack two buttons:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  <mx:VBox>
    <mx:Button label="Example Button 1" />
    <mx:Button label="Example Button 2" />
  </mx:VBox>
</mx:Application>

You can nest containers within containers, as the following example shows, by placing an HBox (a container that automatically arranges the child elements so that they are placed side by side horizontally) inside a VBox:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  <mx:VBox>
    <mx:Button label="Example Button 1" />
    <mx:Button label="Example Button 2" />
    <mx:HBox>
      <mx:Button label="Example Button 3" />
      <mx:Button label="Example Button 4" />
    </mx:HBox>
  </mx:VBox>
</mx:Application>

You can read more about layout containers in Chapter 6.

UI controls

User interface controls are visible interface elements such as buttons, text inputs, lists, and data grids. There are many types of UI controls, and we discuss them in more detail in Chapter 7. You’ve already had a chance to see several examples with a button control.

Setting component properties

When you work with components, you often need to configure them by setting properties. For example, a button component lets you apply a label by setting a property. Every component type has its own unique set of properties that you can set. For example, a button and a VBox clearly have different properties because they do different things. However, despite the difference in the specific properties available for components, you can set the properties using the same techniques. You can set properties of components in several ways:

  • Using tag attributes

  • Using nested tags

  • Using ActionScript

The simplest and most common way to set properties for a component is to use the tag attributes. We already showed several examples of this technique in earlier code examples. For instance, the Application tag allows you to set a layout property using a tag attribute, as in the following example:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

</mx:Application>

You’ll notice that tag attributes always appear in the opening tag following the tag name. A tag can have many attributes, each separated by spaces. The attributes themselves consist of the attribute name, an equals sign, and the value enclosed in quotation marks.

Almost all components (all visible components) have an id property. In most instances of containers and UI controls, you should set the id property, because that is how to reference the instance using data binding or ActionScript. The id property is the name of the component instance, and it must be unique within the document. The value must also follow a few naming rules. Specifically, the id property for a component should consist only of letters, numbers, and underscores, and it should start with either an underscore or a letter, but not a number. The following assigns an id value to a button:

<mx:Button id="exampleButton" label="Example Button" />

You can set most properties (though not the id property) using nested tags as an alternative to tag attributes. The nested tags use the same name as the property/attribute, but they must be prefixed with the correct namespace prefix.

The following example assigns a button label using a nested tag:

<mx:Button id="exampleButton">
  <mx:label>Example Button</mx:label>
</mx:Button>

In most cases, it’s preferable to set properties using attributes rather than nested tags because attributes are a more compact and more readable format. However, there are legitimate use cases that justify using nested tags. For example, some properties require complex values that cannot be represented by a string value placed within quotation marks. One such example is the dataProvider property for a combo box (a drop-down menu component). The dataProvider property of a combo box must be some sort of collection of values. The following example creates a combo box and uses a nested dataProvider tag to populate it with values:

<mx:ComboBox id="exampleComboBox">
  <mx:dataProvider>
    <mx:ArrayCollection>
      <mx:Array>
        <mx:String>A</mx:String>
        <mx:String>B</mx:String>
        <mx:String>C</mx:String>
        <mx:String>D</mx:String>
      </mx:Array>
    </mx:ArrayCollection>
  </mx:dataProvider>
</mx:ComboBox>

Note

Note that you can also set the dataProvider property using ActionScript, which would not require nested tags. However, when you want to use MXML to set the dataProvider property, you must use nested tags, as in this example.

You can also set properties using ActionScript. When you set an id property for a component, you can reference it using that name as an ActionScript object. Most (though not all) component properties have the same names as attributes and as ActionScript properties. We’ll look at working with ActionScript in the next chapter.

Non-visual components

As mentioned earlier, there are two types of non-visual components: data components and utility components. Data components are used to create data structures, such as arrays and collections, and for making remote procedure calls with protocols like SOAP for web services or AMF for Flash Remoting. You can read more about data components in Chapter 17.

Utility components are components used to achieve functionality. Examples of utility components are those used for creating repeating components and for creating data binding between components. Since utility components are responsible for varied, generally unrelated tasks, we haven’t grouped them all in one chapter. Rather, you’ll find discussions of utility components in the context of the topics when you’d most likely use the components. For example, the data binding component is discussed in Chapter 14, and the repeater component is discussed in Chapter 6.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset