Posted by The Fattest on 07/31/2007

7 comments
Skill

Flex Snippet Tutorial - Bindable Meta Tag Part 2

Posted in:

This short tutorial is part two in an ongoing series of tutorials about the Bindable Meta Tag in Flex. If you need a refresher check out the first part. So lets get to it.

Here we have a quick example that shows us binding some data again. But this time instead of having a bunch of [Bindable] variables in our <mx:Script> we are going to create a class to hold this data. Now the neat thing that we can do is create the class and declare the entire class [Bindable]. And this will enable you to use all the properties of this class as if they were each declared [Bindable].

So as you can see in the example we have a couple of fields (Name, Position, and Age) which are bound to some text boxes and labels and as we update the contents of a textbox, its corresponding label updates.

Get Adobe Flash player

The class we create is going to be a very simple data holding object. The only special thing we need to do with this class definition is add the [Bindable] tag above the class declaration. This tells the compiler that we want all the public properties for this class to be bindable. Now this will not make private or protected properties bindable. If you need them to be bindable you need to add the [Bindable] meta tag to them individually. But since our class doesn't have anything but a few public properties and a constructor we are good to go. You can see the class code below.

package src
{
  [Bindable]
  public class EmployeeEins
  {
    public var Name:String;
    public var Position:String;
    public var Age:String;
   
    public function EmployeeEins(name:String, position:String, age:String)
    {
      Name = name;
      Position = position;
      Age = age;
    }
  }
}

Now we have a completely Bindable class to use. Next lets take a quick look at the interface for this example - it is just a typical mxml interface. It has a panel that fills the application area, a few labels, and a couple text boxes. Once everything is in place, we end up with the code below:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
   width="285" height="308" viewSourceURL="files/BindableClassTutorial.mxml">
  <mx:Panel x="0" y="0" width="285" height="308"
     layout="absolute" title="Bindable Class and Properties">
    <mx:Label text="Complete Bindable Class" fontSize="12" x="31" y="10"/>
    <mx:Label text="Name:" x="31" y="36"/>
    <mx:Label text="Position:" x="31" y="64"/>
    <mx:Label text="Age:" x="31" y="94"/>
    <mx:TextInput width="150" id="txtEmpEinsName" x="84" y="34"/>
    <mx:TextInput width="150" id="txtEmpEinsPosition" x="84" y="62"/>
    <mx:TextInput width="150" id="txtEmpEinsAge" x="84" y="92"/>
    <mx:Label text="Name:" x="31" y="148"/>
    <mx:Label text="Position:" x="31" y="176"/>
    <mx:Label text="Age:" x="31" y="206"/>
    <mx:Label id="lblEmpEinsName" x="84" y="148"/>
    <mx:Label id="lblEmpEinsPosition" x="84" y="176"/>
    <mx:Label id="lblEmpEinsAge" x="84" y="206"/>
  </mx:Panel>
</mx:Application>

The next thing we need is a bit of script to instantiate our EmployeeEins class and initialize the values. We do this by adding a function to creationComplete event for our application and a variable for our employee. So our new application tag looks like the following:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
   creationComplete="{initApplication()}" width="285" height="308"
   viewSourceURL="../files/BindableClassTutorial.mxml">

Now its time to add a a <mx:Script> section beneath our application code. This code imports our src files, declares a variable to use, and finally creates the function "initApplication()" (which is called from our application creation complete event). In the initApplication function we set our variable to a new instance of our class and initialize the values through the constructor. Once that is all done, it should look something like this:

<mx:Script>
 <![CDATA[
   import src.*;
   
   [Bindable]
   public var employeeEins:EmployeeEins;
 
   private function initApplication():void
   {
     employeeEins = new EmployeeEins("Charlie", "Janitor", "23");
   }
 ]]>
</mx:Script>

Now, as you remember, we made our class bindable so why do we have to add the bindable tag to the variable as well? This is because when we made our class bindable we told the compiler that it was ok to bind to the public properties of that class, but making the variable bindable tells the compiler that we can now bind to this particular instance of our class. All that is left to do is bind the properties of our class to the labels and text boxes like normal - meaning we set the text properties of our labels and text boxes to the properties of our employee class instance. Also, we need three instances of the <mx:Binding> tag, one for each textbox (these tags will take care of changing the variable as the user changes the contents of the textbox. And all of this leads to the final code below:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
   creationComplete="{initApplication()}" width="285" height="308"
   viewSourceURL="../files/BindableClassTutorial.mxml">
  <mx:Script>
   <![CDATA[
     import src.*;
     
     [Bindable]
     public var employeeEins:EmployeeEins;
     
     private function initApplication():void
     {
       employeeEins = new EmployeeEins("Charlie", "Janitor", "23");
     }
   ]]>
 </mx:Script>
  <mx:Binding source="txtEmpEinsName.text" destination="employeeEins.Name" />
  <mx:Binding source="txtEmpEinsPosition.text" destination="employeeEins.Position" />
  <mx:Binding source="txtEmpEinsAge.text" destination="employeeEins.Age" />
  <mx:Panel x="0" y="0" width="285" height="308" layout="absolute"
     title="Bindable Class and Properties">
    <mx:Label text="Complete Bindable Class" fontSize="12" x="31" y="10"/>
    <mx:Label text="Name:" x="31" y="36"/>
    <mx:Label text="Position:" x="31" y="64"/>
    <mx:Label text="Age:" x="31" y="94"/>
    <mx:TextInput width="150" id="txtEmpEinsName"
       text="{employeeEins.Name}" x="84" y="34"/>
    <mx:TextInput width="150" id="txtEmpEinsPosition"
       text="{employeeEins.Position}" x="84" y="62"/>
    <mx:TextInput width="150" id="txtEmpEinsAge"
       text="{employeeEins.Age}" x="84" y="92"/>
    <mx:Label text="Name:" x="31" y="148"/>
    <mx:Label text="Position:" x="31" y="176"/>
    <mx:Label text="Age:" x="31" y="206"/>
    <mx:Label id="lblEmpEinsName" text="{employeeEins.Name}" x="84" y="148"/>
    <mx:Label id="lblEmpEinsPosition" text="{employeeEins.Position}" x="84" y="176"/>
    <mx:Label id="lblEmpEinsAge" text="{employeeEins.Age}" x="84" y="206"/>
  </mx:Panel>
</mx:Application>

This code should give you a decent understanding of how to use the [Bindable] meta tag on classes and how to bind fields on classes to visual components. If you have any questions about this tutorial please leave a comment. Also look for a part three soon on, which will explain some of the advanced things that can be done with the [Bindable] Meta tag.

Jason
10/30/2007 - 09:36

How would I go about making a dataProvider for a grid bindable?

I have recordset that I'm returning from a webservice and want to populate 4 data grids with the same data (then I'll filter it using flex filter functions).

Lets's call it Data Grid A,B,C,D.

I want to keep A/B and C/D identical as I perform drag/drop actions on them. Basically I want to Take a record from Recordset A or B, drag it to C or D, then RE-bind all the data grids to reflect the changes.

Say if A/B datagrids had
Joe, Bob, Frank and C/D had Sue, Barb, Jan - I take Joe from Grid A and drag him to C/D.. I want A/B to both now reflect that change to (Bob,Frank) and C/D to have (Joe,Sue,Barb,Jan)

Thanks in advance for the help!

reply

Jason
10/30/2007 - 09:43

Ohh and behind the scenes I'm updating these records in the database that the recordset is pulling from, so I could actually just call the webservice again to repopulate the datagrids, but obviously I'd like to avoid that if there's a way to mimic the action without another call to the db.

reply

Kom
01/10/2008 - 07:50

Hi, somewhere I've also seen Bindable tag as

[Bindable]            [Embed("assets/arrow_down.png")]
private var arrowDown:Class;

[Bindable]            [Embed("assets/arrow_left.png")]
private var arrowLeft:Class;

I'm wanted to confirm is including Embed... in the [] braces carries some special meaning while parsing or are just the same as

[Bindable]         Embed("assets/arrow_left.png")
private var arrowLeft:Class;

---------------------------------
Secondly, i've a very basic query... Are all the statements/variables between [Bindable] keyword and any new (blank) line considered as bindable or only the single variable immediately after the Bindable keyword?

thanks!

reply

The Fattest
01/10/2008 - 12:08

Kom,

Yes you need the brackets they let the compiler know that a meta tag is there and should be looked at, let me know if that makes sense. Second only the first variable after the bindable tag will be bindable. If you add Bindable to the entire class though you can bind to any public variable or property of the class.

reply

Vinant Pandey
02/26/2008 - 17:05

If the EmployeeEins class was encapsulated with a get and a set method ...then flex throws an error saying duplicate function name.

can you expalin why ?

reply

Ritesh
03/14/2008 - 17:50

hi,

very nice tutorial. I read all the three parts and really enjoyed reading each of them. Its nicely organized.

Great work

reply

Siva-Srilankan-kalutara
05/08/2008 - 00:16

once u declared as bindable in class level it only effect to the public properties(variables)
in that class.but for private and protected var we have to give again bindable meta tag.so is there any way to say that flex compiler to bindability for all three access levels property by single declaration metatag using class level

reply

Add Comment

Put code snippets inside language tags:
[language] [/language]

Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]

See here for supported languages.

Javascript must be enabled to submit anonymous comments - or you can login.