Building components by using code behind

来源:互联网 发布:java base64源码 编辑:程序博客网 时间:2024/06/12 00:25
 

Building components by using code behind

MXML and ActionScript languages have different own strengths and weaknesses for creating components:

  • When you create composite controls declaratively, MXML makes it easier to create and lay out child controls.
  • When you modify the behavior of components, that is, override their methods, you typically use ActionScript.

Most of the time, you use a combination of MXML and ActionScript when you build Flex components and applications. Earlier versions of Flex have provided several ways of using MXML and ActionScript together:

  • Placing ActionScript statements directly within MXML tags. This is used when defining inline event handlers.
  • Placing ActionScript statements within the <mx:Script> tag.
  • Including external ActionScript files by using the source property of the <mx:Script> tag.

Adobe® Flex™ 2 adds to these methods with a new technique for working with MXML and ActionScript called code behind.

With code behind, you use MXML code to layout your component and you place your ActionScript code in a class definition. To link the two together, you make the ActionScript class the root tag of your MXML component; that is, your MXML component extends the ActionScript class. For example, to create a custom AddressForm component that displays a composite address entry form, you do the following:

  1. Create an ActionScript class called AddressFormClass. You can make this class extend a base Flex class. In this case, you use the layout capabilities of the Form container and make AddressFormClass extend the mx.containers.Form class.
  2. Create an MXML component called AddressForm and make its root tag AddressFormClass.
  3. Use MXML to layout the contents of the AddressForm component.
  4. Use ActionScript to create the logic for the AddressForm component.

Tip: You must declare child controls as public properties in your ActionScript class.

The following example contains the custom AddressForm component described above. The main application file also makes use of code behind and the example also features the CountryComboBox and PaddedPanel components that you created in the other tutorials.

Link: Consider this as an introduction to best practices architecture when building Flex applications. For more information, see the Arp framework — an open source pattern-based framework for creating Flash and Flex applications that uses code behind.

Example

components/AddressFormClass.as

package components{    import mx.events.FlexEvent;    import mx.controls.Button;    import mx.controls.TextInput;    import flash.events.MouseEvent;    import mx.containers.Form;        public class AddressFormClass extends Form    {        // Components in the MXML must be         // declared public. This is a limitation in         // the current version of Flex and may change        // in the future.         public var submitButton:Button;        public var nameInput:TextInput;        public var street:TextInput;        public var city:TextInput;        public var state:TextInput;        public var country:CountryComboBox;                // Constructor        public function AddressFormClass ():void        {            addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);        }                // Creation complete is a good time to add event listeners and         // interact with child components.        private function creationCompleteHandler (event:FlexEvent):void        {            submitButton.addEventListener(MouseEvent.CLICK, submitHandler);        }                // Gets called when the Submit button is clicked        private function submitHandler (event:MouseEvent):void        {            // Gather the data for this form            var addressVO:AddressVO = new AddressVO();            addressVO.name = nameInput.text;            addressVO.street = street.text;            addressVO.city = city.text;            addressVO.state = state.text;            addressVO.country = country.selectedItem as String;                                    var submitEvent:AddressFormEvent = new AddressFormEvent(AddressFormEvent.SUBMIT);            submitEvent.data = addressVO;                                    // Dispatch an event to signal that the form has been submitted             dispatchEvent(submitEvent);        }    }}

components/AddressForm.mxml

<?xml version="1.0" encoding="utf-8"?><custom:AddressFormClass     xmlns:mx="http://www.adobe.com/2006/mxml"    xmlns:custom="components.*">   <mx:FormItem label="Name">        <mx:TextInput id="nameInput"/>    </mx:FormItem>    <mx:FormItem label="Street">        <mx:TextInput id="street"/>    </mx:FormItem>    <mx:FormItem label="City">         <mx:TextInput id="city"/>    </mx:FormItem>    <mx:FormItem label="State/County">         <mx:TextInput id="state"/>    </mx:FormItem>    <mx:FormItem label="Country">         <custom:CountryComboBox id="country"/>    </mx:FormItem>       <mx:Button         id="submitButton"        label="Submit"    /></custom:AddressFormClass>

components/AddressFormEvent.as

package components{    import flash.events.Event;    import components.AddressVO;    public class AddressFormEvent extends Event    {        public static const SUBMIT:String = "submit";        private var _data:AddressVO;        public function AddressFormEvent (eventName:String)        {            super (eventName);        }                public function set data (value:AddressVO):void        {            _data = value;        }                public function get data ():AddressVO        {            return _data;        }    }}

components/AddressVO.as

package components{    public class AddressVO    {        // We are using public properties for the        // value object to keep this example short. In a        // real-world application, make these properties        // private and use implicit accessors to expose them        // so you can do validation, etc. if necessary.         public var name:String;        public var street:String;        public var city:String;        public var state:String;        public var country:String;    }}

components/PaddedPanel.as

package components{    import mx.containers.Panel;    public class PaddedPanel extends Panel    {        public function PaddedPanel()        {            // Call the constructor of the superclass.            super();                        // Give the panel a uniform 10-pixel             // padding on all four sides.            setStyle ("paddingLeft", 10);            setStyle ("paddingRight", 10);            setStyle ("paddingTop", 10);            setStyle ("paddingBottom", 10);        }    }}

components/CountryComboBox.mxml

<?xml version="1.0" encoding="utf-8"?><mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml">    <mx:dataProvider>            <mx:String>United States</mx:String>        <mx:String>United Kingdom</mx:String>        <!-- Add all other countries. -->    </mx:dataProvider></mx:ComboBo</mx:ComboBox>
package components{    import mx.core.Application;    import mx.events.FlexEvent;    import mx.controls.Alert;        import components.AddressFormEvent;    import components.AddressVO;    import flash.utils.describeType;        public class ApplicationClass extends Application    {        // Components in MXML        public var addressForm:AddressForm;                public function ApplicationClass()        {            addEventListener (FlexEvent.CREATION_COMPLETE, creationCompleteHandler);        }                //        // Event handlers        //        private function creationCompleteHandler(event:FlexEvent):void        {            // The custom AddressForm component dispatches a "submit"             // event the form is submitted. Listen for this.             addressForm.addEventListener(AddressFormEvent.SUBMIT, submitHandler);        }                private function submitHandler(event:AddressFormEvent):void        {            // Get the value object (data) from the event object            var data:AddressVO = event.data as AddressVO;                                                // Compose a string to display the contents of the value object to the user.            var msg:String = "You submitted the following information: /r";                        // Use the new introspection API and E4X to get a list of the properties            // in the data object and enumerate over them to compose the string.            var dataProperties:XMLList = describeType(data)..variable;                        for each (var i:XML in dataProperties)             {                var propertyName:String = i.@name;                msg += i.@name + ": " + data[i.@name] + "/r";            }            // Display the contents of the address form to the user.            Alert.show(msg, "Thank you for submitting the form!");        }    }}

Main application MXML file

<?xml version="1.0" encoding="utf-8"?><custom:ApplicationClass     xmlns:custom="components.*"    viewSourceURL="src/CodeBehind/index.html"    width="400" height="310">    <custom:PaddedPanel title="Code Behind">        <custom:AddressForm id="addressForm"/>    </custom:PaddedPanel></custom:ApplicationClass>

Result


To view the full source, right-click the Flex application and select View Source from the context menu.


For more information

For more information, see "Creating Custom ActionScript Components" in Creating and Extending Flex 2 Components.

About the author

Aral Balkan acts and sings, leads development teams, designs user experiences, architects rich Internet applications, and runs OSFlash.org, the London Macromedia User Group, and his company, Ariaware. He loves talking design patterns and writing for books and magazines. He also authored Arp, the open-source RIA framework for the Flash platform. Aral is generally quite opinionated, animated, and passionate. He loves to smile, and can even chew gum and walk at the same time.