Enabling Data Binding for Custom Classes

Data binding is enabled for some types of objects by default, but to make it work for custom classes, enable data binding with the [Bindable] metadata tag which tells the Flex compiler to configure whatever it precedes. Use [Bindable] with:

  • A class

  • A property

  • An implicit getter method

  • An implicit setter method

Note

For data binding to work when using implicit getters and setters, you need a getter and a setter for every property that you want to use data binding.

When you use the [Bindable] metadata tag before a class declaration, it marks all the public properties and all the getter and setter pairs as data-binding-enabled:

[Bindable]
public class Example {

When you use [Bindable] before a property declaration, it sets just that property as data-binding-enabled:

[Bindable]
private var _exampleProperty:String;

When you use [Bindable] before a getter and/or setter method, that method becomes data-binding-enabled. If a getter and setter have the same name, you must place the [Bindable] metadata tag before only one of them. If you have only a getter method, the method works only as the source for data binding. If you have only a setter method, the method works only as the destination for data binding:

[Bindable]
public function get exampleGetter():String {
    return "example";
}

Always enable both the contents of a custom class and an instance of the class (if instantiated using ActionScript) to use the instance for data binding. Consider the simple class in Example 14-3.

Example 14-3. Basic data binding class example

package com.oreilly.programmingflex.binding {

    [Bindable]
    public class DataBindableExample {

        private var _example:String;

        public function get example():String {
            return _example;
        }

        public function set example(value:String):void {
            _example = value;
        }

        public function DataBindableExample() {
            _example = "example";
        }
    }
}

The class in Example 14-4 uses [Bindable] to enable the entire class. But if you want to use an instance of the class in an MXML document as either the source or the destination for data binding, you must declare the instance using the [Bindable] tag as well.

Example 14-4. Implementation of basic data binding

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

    <mx:Script>
        <![CDATA[

            import com.oreilly.programmingflex.binding.DataBindableExample;

            [Bindable]
            private var _dataBindableExample:DataBindableExample;

            private function initializeHandler(event:Event):void {
                _dataBindableExample = new DataBindableExample();
            }

        ]]>
    </mx:Script>
    <mx:VBox>
        <mx:TextInput id="input" />
        <mx:TextInput id="output" />
    </mx:VBox>

    <mx:Binding source="input.text" destination="_dataBindableExample.example" />
    <mx:Binding source="_dataBindableExample.example" destination="output.text" />
</mx:Application>

The preceding example uses the DataBindableExample instance as an intermediary between the two text inputs. This particular example does not demonstrate a useful use case, but it does illustrate a simple working example that shows which elements are necessary to build a custom class that works with data binding. We’ll look at more practical, more complex examples later in this chapter, when we talk about building proxies for endpoints that wouldn’t otherwise be data-binding-enabled.

Customizing Data Binding

Data binding works by dispatching events using the standard Flash Player event model. If you were to look at the generated ActionScript for an application that uses data binding, you would see that classes with bindable properties dispatch events, and where MXML uses data binding syntax, the generated ActionScript class registers event listeners. When you use the [Bindable] tag, the default event type that gets dispatched is propertyChange. In many cases, this is perfectly workable. However, it can introduce inefficiencies when one class has several properties using data binding, because anytime any of the properties changes, all listeners for all changes in all bindable properties for the object instance will receive a notification. It’s more efficient if each property dispatches a unique event name. You get this by adding an event setting for the [Bindable] tag.

[Bindable(event="customEvent")]

In cases where you customize the event name, you also manually dispatch the event.

dispatchEvent(new Event("customEvent"));

Obviously, when you customize the event name, you must add a [Bindable] tag before each property (or getter/setter), rather than using one tag just prior to the class declaration. Example 14-5 uses custom event names.

Example 14-5. Customized data binding

package com.oreilly.programmingflex.binding {

    import flash.events.Event;
    import flash.events.EventDispatcher;

    public class CustomizedDataBindableExample extends EventDispatcher {

        static public const A_CHANGE:String = "aChange";
        static public const B_CHANGE:String = "bChange";

        private var _a:String;
        private var _b:String;

        [Bindable(event="aChange")]
        public function get a():String {
            return _a;
        }

        public function set a(value:String):void {
            _a = value;
            dispatchEvent(new Event(A_CHANGE));
        }

        [Bindable(event="bChange")]
        public function get b():String {
            return _b;
        }

        public function set b(value:String):void {
            _b = value;
            dispatchEvent(new Event(B_CHANGE));
        }

        public function CustomizedDataBindableExample() {
            _a = "a";
            _b = "b";
        }
    }
}

You’ll also notice that the class in the preceding example extends EventDispatcher. When using the Bindable tag without an event attribute, the Flex compiler automatically takes care of configuring the class to dispatch events, even if the class doesn’t explicitly extend EventDispatcher. (Remember that the Flex compiler always compiles in several steps, and that during the first step the compiler converts MXML and ActionScript classes to an intermediate ActionScript stage in which it translates things such as metadata tags into concrete ActionScript implementations.) However, when you specify an event attribute for the Bindable metadata tag, you must dispatch events explicitly. Therefore, if you do not extend EventDispatcher explicitly (or use composition to include an EventDispatcher instance), you'll receive a compiler error because there will be no such method as dispatchEvent(). Therefore, when you use the event attribute, you must account for this either by extending EventDispatcher (as in the preceding example) or by using composition to include an EventDispatcher object and dispatch the events using that object.

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

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