Data binding is the process of tying the data in one object to another object. It provides a convenient way to pass data between the different layers of the application. Data binding requires a source property, a destination property, and a triggering event that indicates when to copy the data from the source to the destination. An object dispatches the triggering event when the source property changes.
Two-way data binding, aka bidirectional data binding, refers to two components acting as the source object for the destination properties of each other. This is possible to do in Flex 3 using a combination of curly braces, <mx:binding> statements, and calls to mx.binding.utils.BindingUtils.bindProperty(). This spec introduces a few shorthand ways to accomplish the same thing with fewer steps.</mx:binding>
This feature has been requested by customers.
Two-way data binding is used whenever two properties need to be tied together, for example, two text fields.
A two-way data binding expression generates two binding expressions, one with the given source and destination, and the other, with the source and destination reversed. Since the destination must be a bindable property or property chain (reference value), the source must be a bindable property or property chain as well. The source and destination must be the same type.
The two ways to specify a two-way data binding are:
(Not currently scheduled to be implemented for Flex 4)
The chain would be extended from bindProperty(), to accept an object that contains not just the name of, and a getter function for, but a setter function as well, for a public bindable property of the respective object.
// Returns and Array of up to two ChangeWatcher objects.
public static function bindPropertyTwoWay(
obj1:Object, chain1:Object,
obj2:Object, chain2:Object,
commitOnly:Boolean = false):Array
In Flex 3, to implement two-way binding, the code would like the following:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:TextInput id="t1" text="{t2.text}"/>
<mx:TextInput id="t2" text="{t1.text}"/>
</mx:Application>
Using the new shorthand two-way binding syntax this could also be written as:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:TextInput id="t1" text="@{t2.text}"/>
<mx:TextInput id="t2"/>
</mx:Application>
A more useful example would be something like:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:XML id="myWebServiceResult"/>
<mx:TextInput id="t1" text="{myWebServiceResult.foo.bar}"/>
<mx:Binding source="t1.text" destination="myWebServiceResult.foo.bar"/>
</mx:Application>
which becomes:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:XML id="myWebServiceResult"/>
<mx:TextInput id="t1" text="@{myWebServiceResult.foo.bar}"/>
</mx:Application>
In Flex 3, if you want to set two-way binding using the <mx:binding> tag you need to set it twice:</mx:binding>
<mx:Binding source="a.property" destination="b.property"/>
<mx:Binding source="b.property" destination="a.property"/>
which becomes:
<mx:Binding source="a.property" destination="b.property" twoWay="true"/>
All of the inline binding expressions below are invalid.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:TextInput id="t1" text="text is @{t2.text}"/>
<mx:TextInput id="t2"/>
<mx:TextInput id="t3" text="@{t4.text.toUpperCase()}"/>
<mx:TextInput id="t4"/>
<mx:Binding source="{t2.text}" destination="@{t4.text}" twoWay="true" />
</mx:Application>
In order to create a complete BindableExpression, the sourceExpression, the xml line number and the destination lvalue or the destination property must be known. For two-way inline binding, there are also additional binding expression flags which need to be set so that the destination path can be generated properly.
Bindable expressions are supported in the many places, not all or which are appropriate for two-way bindable expressions.
Location
Two-way Data Binding Supported
property text
Yes
style text
No
effect text
No
<model>{bindable_expression}</model>
Yes
<mx:xml> top-level* or nodes or attributes
Yes</mx:xml>
<mx:xmllist> top-level* or nodes or attributes
Yes</mx:xmllist>
in <mx:request> for <mx:httpservice>, <mx:remoteobject> and <mx:webservice>
No</mx:webservice></mx:remoteobject></mx:httpservice></mx:request>
in <mx:arguments> for <mx:remoteobject>
No</mx:remoteobject></mx:arguments>
[[ note arg0='* note' ]]
Until bug SDK-16804 is fixed neither one-way or two-way binding will work at the top-level for <mx:xml> or <mx:xmllist>.
[[ /note ]]</mx:xmllist></mx:xml>
I have prototyped enough of this to figure out how data binding is setup.
no additional changes other than described above
none
none
n/a
n/a
n/a
new messages added to appropriate message files
mxml.builder.AbstractBuilder.TwoWayBindingNotAllowedInitializer=Initializer for '${desc}': two-way data binding expression not allowed here.
mxml.builder.AbstractBuilder.TwoWayBindingNotAllowed=Inline two-way data binding expression not allowed here.
mxml.builder.AbstractBuilder.InvalidTwoWayBindingInitializer=Initializer for '${desc}': invalid two-way binding expression: ${text}.
mxml.builder.AbstractBuilder.InvalidTwoWayBinding=Invalid two-way binding expression: ${text}.
n/a
Customer asked
[[ quote ]]
I saw in a promotional article that the methods for setting up 2 way binds are going to be revamped in Flex 4. Is this in the alpha release yet? If not does anyone know what is planned? Is it going to support 2 way binds on E4X statements? And most importantly, can the two way binds on E4X be setup in actionscript via BindUtil calls?
[[ /quote ]]
Using the inline notation, it will be possible to bind on E4X statements. Adding support for E4X statements to BindingUtils is another task which needs to be prioritized and scheduled.
Since this is a new feature it will need to be documented.