« Firefox 2 Live Titles | Main | Apollo Application Demos »

November 30, 2006

Fun with Flex Data Binding

I'm working on a new Apollo application, and I've been having some fun with data binding in Flex. In case you haven't used data binding yet, it is simply a way to bind an object to a component so that changes to that object are automatically picked up by that component, and the component automatically updates itself appropriately. Here's a simple example (not valid MXML, but you get the point):

[Bindable]
private var labelText:String = "This is a label";

<mx:Label text="{labelText}"/>

Now that labelText is bound to the label component, anytime the labelText variable changes, the text of the label automatically changes, as well.

Ok, that's a basic example. Here's a more interesting usage:

[Bindable]
private var items:ArrayCollection;

<mx:Label text="You have {items.length} items."/>

All I'm doing in the example above is combining bound data with a static string so that the label will always show the current number of items in the ArrayCollection. The beauty of data binding is that is saves you the trouble of updating components manually when certain events occur. You just focus on the logic of your application (adding and removing items from the ArrayCollection, in this case), and the label just takes care of itself.

Here's a slightly more interesting example:

<mx:TextInput id="myInput"/>
<mx:Button label="Do Something" enabled="{myInput.text.length > 0}"/>

This is an example, I'm binding an expression to a component attribute. The length property of the text input is bindable, so whenever it changes, the expression that I've bound to the enabled attribute is evaluated. If the length is greater than zero, true is returned, and the button is enabled, but if the length is zero (meaning nothing has been typed into the text input), the button automatically disables itself.

Let's take this one step further:

private function isButtonEnabled(someString:String, itemLength:uint):Boolean
{
	if (...) {
  		myButton.label = "I'm enabled!";
  		return true;
  	} else {
  		myButton.label = "I'm disabled.";
  		return false;
  	}
}

<mx:Button id="myButton" enabled="{isButtonEnabled(someString, items.length)}"/>

In this example, I appear to be binding a function call to the enabled attribute of the button, but in fact I'm actually binding someString and the length property of items to the button. Whenever either changes, the entire expression is evaluated, which causes my function to be called. The arguments of my function call are basically just an arbitrarily long list of objects that my button may be interested in, and may not even be used in the function itself to decide what to do or return. Another advantage of this approach is that my function may do more than just return true or false. I can change the label of the button, or do any number of other things that are appropriate for the current state of the application.

There are a lot of other fun things that can be done with data binding, but I'm not going to go any further because I haven't decided where to draw the line yet between using data binding to its full potential, and abusing it. That said, if you have any good data binding tips or tricks, I'd love to hear them.

Posted by cantrell at November 30, 2006 10:17 AM

Comments

This is a fantastic enhancement to Flex. It really cuts the number of listeners that you have to use.

Do you know if this is going to be as easy in the Flash 9 IDE? (BLAZE)

Posted by: Daniel Larsen at December 1, 2006 1:21 PM

Very good but the developers need direct connectors to database.

Posted by: Juan Antonio at December 10, 2006 12:50 AM

I think these blog is really useful for new comers and Excellent resource list.

Posted by: Romina Miersch at February 24, 2007 8:57 PM

The shortest draft of the Data Binding functionality, excellent summary!

Posted by: Shomiron Das Gupta at May 27, 2007 10:01 PM

very usefull blog, gret work. Many greetings from germany

Posted by: tee at June 11, 2007 1:08 PM

Very good but the developers need direct connectors to database.

Posted by: Bramka sms darmowa at June 12, 2007 4:30 PM

Very interesting blog

Posted by: Wyniki lotto at June 12, 2007 4:32 PM

These are good examples of using bindings in MXML. The documentation, unfortunately, isn't as intuitive in the samples it provides.

@Juan Antonio/Bramka sms - read about AS3's new MySQL library.

Posted by: Chris Charlton at June 13, 2007 4:00 PM

I think this article is very useful to solve probs similar to this. I use the Data Binding usually: excellent summary

Posted by: Erin Meyer at June 17, 2007 11:29 PM

If U think Flex should have direct connections to database, U do not understand Flex.

Posted by: CyberSan at July 1, 2007 1:03 PM

very helpful

Posted by: kyle at July 5, 2007 9:59 PM

Thanks for very interesting article. btw. I really enjoyed reading all of your posts. It’s interesting to read ideas, and observations from someone else’s point of view… makes you think more. So please keep up the great work. Greetings.

Posted by: Hundehalsband at July 14, 2007 4:31 AM

How can i connect Flex to SQL Server 2000 or Access database. so that i can bind dynamic data to Pie charts and data grid etc.

pls tell me asap

Posted by: hello world at July 22, 2007 10:25 PM

But how can I move that //enabled="{isButtonEnabled(someString, items.length)}"//
part to ActionScript? I´m trying to keep my mxml clean for any code.

Posted by: Dondo at August 8, 2007 1:02 AM

try mx.binding.utils.BindingUtils

Posted by: Tomislav at December 25, 2007 4:14 PM

the 1st couple example I thought, "Done that before" but the example with the function was a really good idea.

I was thinking to use a getter function, but it would not know when to dispatch the binding.

Nice trick

Posted by: Eric Goeken at December 8, 2008 1:03 PM

very nice blog..
it helped me a lot in understanding the binding concept...
i am very thankful to the writer..
NEAT AND CLEAR

Posted by: Gowri sankar at March 18, 2009 4:22 AM

Thanks for the examples. I never thought to pass properties as parameters to a function to force those parameters to be bound. I'm glad I found this post!

Posted by: Connor Garvey at April 17, 2009 12:57 PM

Noob questions...

Can you help me figure out why the following won't work for me? I am so frustrated!

//MyComponent.mxml


[Bindable]
public var url:String;

public function setAndCallService():void {
url = "http://localhost:8888/blah/blah/blah";
serv.send();
}

private function serv_fault(evt:FaultEvent):void {
trace("serv fault occurred: " + error.text);
trace("url " + url);
error.visible = true;
}

//... the rest of the file ...

What occurs is that the serv.send() gets called, and serv_fault is then called and the first trace line indicates that no URL was given to the HTTPService component. and yet the url gets printed out by the second trace line correctly as "http://....blah/blah".

If you have any extra time, might you be able to explain why if I have [Bindable] set for a private property, why I also need [Bindable] by the getter/setter for that property (and which? the getter or the setter?

Thanks very much.

Posted by: mirie at May 22, 2009 9:28 AM




Remember Me?

(you may use HTML tags for style)

Copyright © 2009 Adobe Systems Incorporated. All rights reserved.
Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy (updated 07-14-2009).