Question: How to use bi-directional
binding.
Answer: We can define a
bidirectional data binding using one of the following methods:
1. Define two objects that specify as the source a property of
the other object. In the following example, input1 specifies input2.text as the
source property, and input2 specifies input1.text as the source property. Any
change to input1.text updates input2.text, and any change to input2.text
updates input1.text:
<!-- Specify data binding for both controls. -->
<s:TextInput id="input1" text="{input2.text}"/>
<s:TextInput id="input2" text="{input1.text}"/>
2. Use the @{bindable_property}
syntax for one source
property, as the following example shows:
<!-- Specify data binding for both controls. --> <s:TextInput id="input1" text="@{input2.text}"/> <s:TextInput id="input2"/>
Note: The property definition that includes
the @{bindable_property} syntax i s called the primary property.
If the primary property has not had a value assigned to it, the binding to it
occurs first, before a binding to the other property.
3. Use the twoWay property of the tag, as the
following example shows:
<fx:Binding source="input1.text" destination="input2.text" twoWay="true”/>
Because both the source and the destination properties must
resolve to a bindable property or property chain at compile time, neither
property value can include a binding expression.
<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">
<s:layout>
<s:VerticalLayout paddingTop="10"/>
</s:layout>
<s:Label text="Specify data binding for both controls."/>
<s:TextInput id="input1" text="{input2.text}"/>
<s:TextInput id="input2" text="{input1.text}"/>
<s:Label text="Use the bidirectional data binding syntax."/>
<s:TextInput id="input3" text="@{input4.text}"/>
<s:TextInput id="input4"/>
<s:Label text="Use the Binding tag."/>
<s:TextInput id="input5"/>
<s:TextInput id="input6"/>
<fx:Binding source="input5.text" destination="input6.text" twoWay="true"/>
</s:Application>
Though bi-directional binding is
supported at most of the places, it is not supported at the following places.
Expression
|
Binding Supported
|
Style Properties
|
No
|
Effect Properties
|
No
|
The request property of the HttpService, RemoteObject and WebService class
|
No
|
The arguments property of the RemoteObject class.
|
No
|
Question: Give example of using
functions as the source for a data binding.
Answer: Two common techniques
with functions are to use bindable properties as arguments to the function to
trigger the function, or to trigger the function in response to a binding
event.
Using functions that take bindable properties as arguments
<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">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Declarations>
<mx:CurrencyFormatter id="usdFormatter" precision="2" currencySymbol="$" alignSymbol="left"/>
</fx:Declarations>
<s:TextInput id="myTI" text="Enter number here"/>
<s:TextArea text="{usdFormatter.format(myTI.text)}"/>
</s:Application>
In this example, Flex calls the CurrencyFormatter.format() method to update
the TextArea control every
time the text property of the TextInput control is modified.
Binding to functions in response to a data-binding event
<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">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import flash.events.Event; // Define a function that gets invoked
// in response to the myFlagChanged event.
[Bindable(event="myFlagChanged")]
private function isEnabled():String
{
if (myFlag)
return 'true';
else
return 'false';
}
private var _myFlag:Boolean = false;
// Define a setter method that dispatches the
// myFlagChanged event to trigger the data binding.
public function set myFlag(value:Boolean):void {
_myFlag = value;
dispatchEvent(new Event("myFlagChanged"));
}
public function get myFlag():Boolean {
return _myFlag;
}
]]>
</fx:Script>
<!-- Use the function as the source of a data binding expression. -->
<s:TextArea id="myTA" text="{isEnabled()}"/>
<!-- Modify the property, causing the setter method to dispatch the
myFlagChanged event to trigger data binding. -->
<s:Button label="Clear MyFlag" click="myFlag=false;"/>
<s:Button label="Set MyFlag" click="myFlag=true;"/>
</s:Application>
We use the [Bindable] metadata tag to specify to Flex to invoke the isEnabled()function in
response to the event myFlagChanged. When the myFlag setter gets called, it dispatches the myFlagChanged event to trigger
any data bindings that use the isEnabled()function as the source:
Question: Give example of using data
binding with objects.
Answer: There is a difference
between binding to an object or binding to properties of an object.
Binding to Objects
package myComponents
{
public class NonBindableObject extends Object {
public function NonBindableObject() { super(); }
public var stringProp:String = "String property";
public var intProp:int = 52;
}
}
<!-- binding/WholeObjectBinding.mxml -->
<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" creationComplete="initObj();">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import myComponents.NonBindableObject;
[Bindable]
public var myObj:NonBindableObject = new NonBindableObject();
[Bindable]
public var anotherObj:NonBindableObject = new NonBindableObject();
public function initObj():void {
anotherObj.stringProp = 'anotherObject';
anotherObj.intProp = 8;
}
]]>
</fx:Script>
<!-- Data binding updated at application startup. -->
<s:Label id="text1" text="{myObj.stringProp}"/>
<!-- Data binding updated at application startup. -->
<s:Label id="text2" text="{myObj.intProp}"/>
<!-- Data bindings to stringProp not updated. -->
<s:Button label="Change myObj.stringProp"
click="myObj.stringProp = 'new string';"/>
<!-- Data bindings to intProp not updated. -->
<s:Button label="Change myObj.intProp" click="myObj.intProp = 10;"/>
<!-- Data bindings to myObj and to myObj properties updated. -->
<s:Button label="Change myObj"
click="myObj = anotherObj;"/>
</s:Application>
Binding to properties of Objects
package myComponents{
// binding/myComponents/BindableObject.as
// Make all class properties bindable.
[Bindable]
public class BindableObject extends Object {
public function BindableObject() { super(); }
public var stringProp:String = "String property";
public var intProp:int = 52;
}
}
//Main Changes
<!-- Data bindings to stringProp updated. -->
<s:Button label="Change myObj.stringProp"
click="myObj.stringProp = 'new string';"/>
<!-- Data bindings to intProp updated. -->
<s:Button label="Change myObj.intProp" click="myObj.intProp = 10;"/> <!-- Data bindings to myObj and to myObj properties updated. --> <s:Button label="Change myObj" click="myObj = anotherObj;"/>
Question: Give example of using data
binding with array.
Answer: When working with
arrays, such as Array or ArrayCollection objects, we can define the array as
source or destination of binding expression.
Note: When defining a data binding expression
that uses an array as the source of a data binding expression, the array should
be of type ArrayCollection because the ArrayCollection class dispatches an
event when the array or the array elements change to trigger data binding. For
example, a call to ArrayCollection.addItem(), ArrayCollection.addItemAt(), ArrayCollection.removeItem(), and ArrayCollection.removeItemAt() all trigger data binding.
Binding to arrays
<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">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var myAC:ArrayCollection = new ArrayCollection([ "One",
"Two", "Three", "Four"]);
]]>
</fx:Script>
<!-- Data binding updated at application startup, when myAC is
modified, and when an element of myAC is modifed. -->
<s:List width="150" dataProvider="{myAC}"/>
<!-- Data bindings to myAC updated. -->
<s:Button label="Change Element" click="myAC[0]='mod One'"/>
<!-- Data bindings to myAC updated. -->
<s:Button label="Add Element" click="myAC.addItem('new element');"/>
</s:Application>
Binding to array elements
We can define individual array
element as source and destination for binding expression.
<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">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var myAC:ArrayCollection = new ArrayCollection([ "One",
"Two", "Three", "Four"]);
[Bindable]
public var myAC2:ArrayCollection = new ArrayCollection([ "Uno",
"Dos", "Tres", "Quatro"]); ]]>
</fx:Script>
<!-- Data binding updated at application startup and when myAC
modified. -->
<s:Label id="text1" text="{myAC[0]}"/>
<!-- Data binding updated at application startup, when myAC modified,
and when myAC[0] modified. -->
<s:Label id="text2" text="{myAC.getItemAt(0)}"/>
<s:Button id="button1" label="Change Element"
click="myAC[0]='new One'"/>
<s:Button id="button2" label="Change ArrayCollection"
click="myAC=myAC2"/>
</s:Application>
If you specify an array element as the source of a data
binding expression by using the square bracket syntax, [], data binding is only
triggered when the application starts and when the array or a reference to the
array is updated; data binding is not triggered when the individual array
element is updated. The compiler issues a warning in this situation. However,
the data binding expression myAC.getItemAt(0) is triggered when an array element
changes. Therefore, the text2 Text control is updated when we click button1,
while text1 is not. When using an array element as the source of a data binding
expression, you should use the ArrayCollection.getItemAt() method in the binding expression.
Clicking button2 copies myAC2 to myAC, and triggers all data bindings to array
elements regardless of how you implemented them.
Question: What are the difference
between binding at compile time (using mxml) and binding at runtime (using
Action script)?
Answer: 1. We cant use any action script code in bindProperty or bindSetter() method. Instead bindSetter() specify a method to
call when binding occurs.
2. We cannot include
an E4X expression in data binding expression in AS.
3. We cannot include
functions or array elements in property chains in a data binding expressions
defined by
bindProperty() or bindSetter() method.
4. MXML compiler has
better warning and error detection support than runtime data binding by
2 comments:
Wahh Mittal ji..kamal ka kaam kiya hai. Hats off to you bro..keep up good work.
Thanks Jameel and sorry for late response.
Post a Comment