Data binding—the process of passing the data in one object to another object automatically—is one of the most used and useful features when building Flex and Adobe AIR applications. At the same time, however, data binding can slow application initialization and cause frustration when developers don’t fully understand how the mechanism works. It is a good idea to make sure you are using it correctly and only when needed. In this article, I’ve compiled a list of ten common pitfalls and mistakes that developers are susceptible to when building an application that uses data binding.
There are cases where the binding operation just does not seem to work, and you end up frustrated and unsure of what to do.
Exceptions and errors that are thrown by binding expressions, or in binding functions called within the binding framework, are silently captured. As a result, you will not see a runtime exception as you might expect in the debug version of Flash Player. Not only does the binding not work, but no errors are shown.
Why are errors being silently captured?
The code that implements the binding mechanism requires several conditions to be met before the binding will occur. The binding mechanism will swallow any errors to prevent runtime exceptions from being thrown at runtime. This is a good thing since you do not want to see these (possibly) unexpected errors in your application.
Consider the following simple binding example:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="1024" minHeight="768"
preinitialize="handlePreinitialize()">
<fx:Script>
<![CDATA[
[Bindable]
private var xml:XML =
<users>
<user>
<name>EladElrom</name>
<address>1 Wall Street</address>
</user>
</users>;
protected function handlePreinitialize():void
{
xml = null;
//BindingManager.debugBinding("label.text");
}
]]>
</fx:Script>
<s:Label id="label" text="{xml.user.name}"/>
</s:Application>
I have added an xml variable binding to a Label component. The code would have worked fine; however, I have set the xml variable to null during the pre-initialization of the component. The event was dispatched at the beginning of the component initialization sequence, so the Label component was not set yet. The xml variable gets set to null, so there is no name property on the xml object. If you run this application, you’ll notice that binding does not occur and the errors have been silently captured.
Using binding in place of direct assignment
In situations where you do not need to bind and you can achieve the same effect with direct assignment, then it is best to avoid binding. I have seen this type of mistake in many shapes and forms.
The code below illustrates one example:
minWidth="1024" minHeight="768">
private var text:String;
]]>
The code defines a TextInput control with a text property binding to the text private variable. It looks harmless enough, right? I have seen these types of tags often in Flex applications. The Flex compiler generates code to allow the binding. You will find that although you do not need to bind the text String since it is a one-time assignment, the compiler still generates code to accommodate binding of the property. Additionally, there are cases where you want to unbind after the assignment or remove the binding code to reduce overhead, but you will not be able to do so using the
Forgetting to unbind and risking memory leaks
You can use the
* The bindProperty() method is a static method used to bind a public property.
* The bindSetter() method is a static method used to bind a setter function.
Take a look at the static bindProperty method signature:
public static function bindProperty(
site:Object, prop:String,
host:Object, chain:Object,
commitOnly:Boolean = false,
useWeakReference:Boolean = false):ChangeWatcher