| <?xml version="1.0" encoding="UTF-8"?> |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| <!DOCTYPE html |
| PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| <html lang="en-us" xml:lang="en-us"> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> |
| <meta name="DC.Type" content="topic"/> |
| <meta name="DC.Title" content="Data binding"/> |
| <meta name="DC.Format" content="XHTML"/> |
| <meta name="DC.Identifier" content="WS2db454920e96a9e51e63e3d11c0bf69084-7fe7_verapache"/> |
| <link rel="stylesheet" type="text/css" href="commonltr.css"/> |
| <title>Data binding</title> |
| </head> |
| <body id="WS2db454920e96a9e51e63e3d11c0bf69084-7fe7_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7fe7_verapache"><!-- --></a> |
| |
| |
| <h1 class="topictitle1">Data binding</h1> |
| |
| <div> |
| <p>Data binding lets you pass data between client-side objects |
| in a Flex application. Binding automatically |
| copies the value of a property of a source object to a property |
| of a destination object when the source property changes. </p> |
| |
| </div> |
| |
| <div class="nested1" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fff_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fff_verapache"><!-- --></a> |
| <h2 class="topictitle2">About data binding</h2> |
| |
| |
| <div> |
| <p> |
| |
| <em>Data binding</em> 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. </p> |
| |
| <p> |
| Flex provides three |
| ways to specify data binding: the curly braces (<samp class="codeph">{}</samp>) |
| syntax in MXML, the <a href="mxml/binding.html" target="_blank"><fx:Binding></a> tag |
| in MXML, and the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/binding/utils/BindingUtils.html" target="_blank">BindingUtils</a> methods |
| in ActionScript. The following example uses the curly braces (<samp class="codeph">{}</samp>) |
| syntax to show a Label control that gets its data from a TextInput |
| control’s <samp class="codeph">text</samp> property: </p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/BasicBinding.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"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <s:TextInput id="myTI" text="Enter text here"/> |
| <s:Label id="myText" text="{myTI.text}"/> |
| </s:Application></pre> |
| |
| <p>The property name inside the curly braces is the source property |
| of the binding expression. When the value of the source property |
| changes, Flex copies the current value of the source property, <samp class="codeph">myTI.text</samp>, |
| to the destination property, the Label control’s <samp class="codeph">text</samp> property. </p> |
| |
| <p>You can include ActionScript code and E4X expressions as part |
| of the data binding expressions, as the following example shows: </p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/BasicBindingWithAS.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"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <s:TextInput id="myTI"/> |
| <s:Label id="myText" text="{myTI.text.toUpperCase()}"/> |
| </s:Application></pre> |
| |
| <p>In this example, you use the ActionScript method <samp class="codeph">String.toUpperCase()</samp> to |
| convert the text in the source property to upper case when Flex |
| copies it to the destination property. For more information, see <a href="flx_databinding_db.html#WS2db454920e96a9e51e63e3d11c0bf69084-7ccc_verapache">Using |
| ActionScript in data binding expressions</a> and <a href="flx_databinding_db.html#WS2db454920e96a9e51e63e3d11c0bf69084-7ccb_verapache">Using |
| an E4X expression in a data binding expression</a>. </p> |
| |
| <p> |
| You can use |
| the <a href="mxml/binding.html" target="_blank"><fx:Binding></a> tag |
| as an alternative to the curly braces syntax. When you use the <samp class="codeph"><fx:Binding></samp> tag, |
| you provide a source property in the <samp class="codeph"><fx:Binding></samp> tag’s <samp class="codeph">source</samp> property |
| and a destination property in its <samp class="codeph">destination</samp> property. |
| The following example uses the <samp class="codeph"><fx:Binding></samp> tag to |
| define a data binding from a TextInput control to a Label control:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/BasicBindingMXML.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"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <fx:Binding source="myTI.text" destination="myText.text"/> |
| |
| <s:TextInput id="myTI"/> |
| <s:Label id="myText"/> |
| </s:Application></pre> |
| |
| <p>In contrast to the curly braces syntax, you can use the <samp class="codeph"><fx:Binding></samp> tag |
| to completely separate the view (user interface) from the model. |
| The <samp class="codeph"><fx:Binding></samp> tag also lets you bind multiple |
| source properties to the same destination property because you can |
| specify multiple <samp class="codeph"><fx:Binding></samp> tags with the |
| same destination. For an example, see <a href="flx_databinding_db.html#WS2db454920e96a9e51e63e3d11c0bf69084-7cca_verapache">Binding |
| more than one source property to a destination property</a>. </p> |
| |
| <p>The curly braces syntax and the <samp class="codeph"><fx:Binding></samp> tag |
| both define a data binding at compile time. You can also use ActionScript |
| code to define a data binding at run time, as the following example |
| shows:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/BasicBindingAS.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"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <fx:Script> |
| <![CDATA[ |
| import mx.binding.utils.*; |
| |
| // Define data binding. |
| public function initBindingHandler():void { |
| BindingUtils.bindProperty(myText, "text", myTI, "text"); |
| } |
| ]]> |
| </fx:Script> |
| |
| <s:TextInput id="myTI"/> |
| <s:Label id="myText" preinitialize="initBindingHandler();"/> |
| </s:Application></pre> |
| |
| <p>In this example, you use the static <samp class="codeph">BindingUtils.bindProperty()</samp> method |
| to define the binding. You can also use the <samp class="codeph">BindingUtils.bindSetter()</samp> method |
| to define a binding to a function. For more information, see <a href="flx_databinding_db.html#WS2db454920e96a9e51e63e3d11c0bf69084-7cc9_verapache">Defining |
| data bindings in ActionScript</a>.</p> |
| |
| <p>Notice in this example that you use the <samp class="codeph">preinitialize</samp> event |
| to define the data binding. This is necessary because Flex triggers |
| all data bindings at application startup when the source object |
| dispatches the <samp class="codeph">initialize</samp> event. For more information, |
| see <a href="flx_databinding_db.html#WS2db454920e96a9e51e63e3d11c0bf69084-7cc8_verapache">When |
| data binding occurs</a>. </p> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf69084-7cc8_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7cc8_verapache"><!-- --></a> |
| <h3 class="topictitle3">When data binding occurs</h3> |
| |
| |
| <div> |
| <p>Binding occurs under the following circumstances:</p> |
| |
| <ol> |
| <li> |
| <p>The binding source dispatches an event because the source |
| has been modified.</p> |
| |
| <p>This event can occur at any time during |
| application execution. The event triggers Flex to copy the value |
| of the source property to the destination property.</p> |
| |
| </li> |
| |
| <li> |
| <p>At application startup when the source object dispatches |
| the <samp class="codeph">initialize</samp> event. </p> |
| |
| <p>All data bindings |
| are triggered once at application startup to initialize the destination |
| property. </p> |
| |
| </li> |
| |
| </ol> |
| |
| <p>To monitor data binding, you can define a binding watcher that |
| triggers an event handler when a data binding occurs. For more information, |
| see <a href="flx_databinding_db.html#WS2db454920e96a9e51e63e3d11c0bf69084-7cc7_verapache">Defining |
| binding watchers </a>.</p> |
| |
| <p>The <samp class="codeph">executeBindings()</samp> method of the UIComponent |
| class executes all the bindings for which a UIComponent object is |
| the destination. All containers and controls, as well as the Repeater |
| component, extend the UIComponent class. The <samp class="codeph">executeChildBindings()</samp> method |
| of the Container and Repeater classes executes all of the bindings |
| for which the child UIComponent components of a Container or Repeater |
| class are destinations. All containers extend the Container class.</p> |
| |
| <p>These methods give you a way to execute bindings that do not |
| occur as expected. By adding one line of code, such as a call to |
| the <samp class="codeph">executeChildBindings()</samp> method, you can update |
| the user interface after making a change that does not cause bindings |
| to execute. However, you should only use the <samp class="codeph">executeBindings()</samp> method |
| when you are sure that bindings do not execute automatically. </p> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ffd_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ffd_verapache"><!-- --></a> |
| <h3 class="topictitle3">Properties that support data binding</h3> |
| |
| |
| <div> |
| <p>You can use all properties of an object as the destination |
| of a data binding expression. However, to use a property as the |
| source of a data binding expression, the source object must be implemented |
| to support data binding, which means that the object dispatches |
| an event when the value of the property changes to trigger the binding. |
| In this topic, a property that can be used as the source of a data-binding |
| expression is referred to as a <em>bindable</em> property.</p> |
| |
| <p>In the <em> |
| <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/" target="_blank">ActionScript 3.0 Reference for the Adobe<sup>®</sup> |
| Flash<sup>®</sup> Platform</a> |
| </em>, a property that can be used as the source |
| of a data binding expression includes the following statement in |
| its description:</p> |
| |
| <p>“This property can be used as the source for data binding.” </p> |
| |
| <div class="section" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ffd_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7ffc_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ffd_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7ffc_verapache"><!-- --></a><h4 class="sectiontitle">Using |
| read-only properties as the source for data binding</h4> |
| |
| <p>You |
| can use a read-only property defined by a getter method, which means |
| no setter method, as the source for a data-binding expression. Flex |
| performs the data binding once when the application starts. </p> |
| |
| </div> |
| |
| <div class="section" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ffd_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7ffb_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ffd_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7ffb_verapache"><!-- --></a><h4 class="sectiontitle">Using |
| static properties as the source for data binding</h4> |
| |
| <p>You can |
| automatically use a static constant as the source for a data-binding expression. |
| Flex performs the data binding once when the application starts. </p> |
| |
| <p>You |
| can use a static variable as the source for a data-binding expression. |
| Flex performs the data binding once when the application starts.</p> |
| |
| </div> |
| |
| <div class="section" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ffd_verapache__WS2db454920e96a9e51e63e3d11c0bf69084-7cc6_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ffd_verapache__WS2db454920e96a9e51e63e3d11c0bf69084-7cc6_verapache"><!-- --></a><h4 class="sectiontitle">Creating |
| properties to use as the source for data binding</h4> |
| |
| <p>When |
| you create a property that you want to use as the source of a data |
| binding expression, Flex can automatically copy the value of the |
| source property to any destination property when the source property |
| changes. To signal to Flex to perform the copy, you must use the <samp class="codeph">[Bindable]</samp> data |
| tag to register the property with Flex. </p> |
| |
| <p>The <samp class="codeph">[Bindable]</samp> metadata |
| tag has the following syntax:</p> |
| |
| <pre class="codeblock"> [Bindable] |
| [Bindable(event="eventname")]</pre> |
| |
| <p>You can optionally |
| omit the <samp class="codeph">event</samp> keyword, and specify the tag as |
| shown below:</p> |
| |
| <pre class="codeblock">[Bindable("eventname")]</pre> |
| |
| <p>If |
| you omit the event name, Flex automatically creates an event named <samp class="codeph">propertyChange</samp>, |
| and Flex dispatches that event when the property changes to trigger |
| any data bindings that use the property as a data-binding source. |
| If you specify the event name, it is your responsibility to dispatch |
| the event when the source property changes. For more information |
| and examples of using the <samp class="codeph">[Bindable]</samp> metadata tag, |
| see <a href="flx_databinding_db.html#WS2db454920e96a9e51e63e3d11c0bf69084-7cc5_verapache">Using |
| the Bindable metadata tag</a>.</p> |
| |
| <p>The following example makes |
| the <samp class="codeph">maxFontSize</samp> and <samp class="codeph">minFontSize</samp> properties |
| that you defined as variables usable as the sources for data bindings expressions:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/FontPropertyBinding.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"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <fx:Script> |
| <![CDATA[ |
| // Define public vars for tracking font size. |
| [Bindable] |
| public var maxFontSize:Number = 15; |
| |
| [Bindable] |
| public var minFontSize:Number = 5; |
| ]]> |
| </fx:Script> |
| |
| <s:Label text="{maxFontSize}"/> |
| <s:Label text="{minFontSize}"/> |
| |
| <s:Button click="maxFontSize=20; minFontSize=10;"/> |
| </s:Application></pre> |
| |
| <p>When you click the Button control, |
| you update the values of the <samp class="codeph">maxFontSize</samp> and <samp class="codeph">minFontSize</samp> properties, |
| and trigger a data binding update to the Label controls. </p> |
| |
| <div class="note"><span class="notetitle">Note:</span> If you omit the <samp class="codeph">[Bindable]</samp> metadata |
| tag, the compiler issues a warning stating that the data binding |
| mechanism cannot detect changes to the property. For more information, |
| see <a href="flx_databinding_db.html#WS2db454920e96a9e51e63e3d11c0bf69084-7cc5_verapache">Using |
| the Bindable metadata tag</a>.</div> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff9_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff9_verapache"><!-- --></a> |
| <h3 class="topictitle3">Data binding uses</h3> |
| |
| |
| <div> |
| <p>Common uses of data binding include the following:</p> |
| |
| <ul> |
| <li> |
| <p>To bind properties of user interface controls to other |
| user interface controls.</p> |
| |
| </li> |
| |
| <li> |
| <p>To bind properties of user interface controls to a middle-tier |
| data model, and to bind that data model’s fields bound to a data |
| service request (a three-tier system).</p> |
| |
| </li> |
| |
| <li> |
| <p>To bind properties of user interface controls to data service |
| requests.</p> |
| |
| </li> |
| |
| <li> |
| <p>To bind data service results to properties of user interface |
| controls.</p> |
| |
| </li> |
| |
| <li> |
| <p>To bind data service results to a middle-tier data model, |
| and to bind that data model’s fields to user interface controls. |
| For more information about data models, see <a href="flx_datamodels_dm.html#WS2db454920e96a9e51e63e3d11c0bf69084-7ff3_verapache">Storing |
| data</a>.</p> |
| |
| </li> |
| |
| <li> |
| <p>To bind an ArrayCollection or XMLListCollection object to |
| the <samp class="codeph">dataProvider</samp> property of a List-based control.</p> |
| |
| </li> |
| |
| <li> |
| <p>To bind individual parts of complex properties to properties |
| of user interface controls. An example would be a master-detail |
| scenario in which clicking an item in a List control displays data |
| in several other controls.</p> |
| |
| </li> |
| |
| <li> |
| <p>To bind XML data to user interface controls by using ECMAScript |
| for XML (E4X) expressions in binding expressions.</p> |
| |
| </li> |
| |
| </ul> |
| |
| <p>Although binding is a powerful mechanism, it is not appropriate |
| for all situations. For example, for a complex user interface in |
| which individual pieces must be updated based on strict timing, |
| it would be preferable to use a method that assigns properties in |
| order. Also, binding executes every time a property changes, so |
| it is not the best solution when you want changes to be noticed |
| only some of the time.</p> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested1" id="WS2db454920e96a9e51e63e3d11c0bf69084-7cc0_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7cc0_verapache"><!-- --></a> |
| <h2 class="topictitle2">Data binding examples</h2> |
| |
| |
| <div> |
| <p/> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff7_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff7_verapache"><!-- --></a> |
| <h3 class="topictitle3">Using data binding with data models</h3> |
| |
| |
| <div> |
| <p>In the following example, a set of UI control properties |
| act as the binding source for a data model. For more information |
| about data models, see <a href="flx_datamodels_dm.html#WS2db454920e96a9e51e63e3d11c0bf69084-7ff3_verapache">Storing |
| data</a>.</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/BindingBraces.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"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <fx:Declarations> |
| <!-- Data model stores registration data that user enters. --> |
| <fx:Model id="reg"> |
| <registration> |
| <name>{fullname.text}</name> |
| <email>{email.text}</email> |
| <phone>{phone.text}</phone> |
| <zip>{zip.text}</zip> |
| <ssn>{ssn.text}</ssn> |
| </registration> |
| </fx:Model> |
| </fx:Declarations> |
| |
| <!-- Form contains user input controls. --> |
| <s:Form> |
| <s:FormItem label="Name" required="true"> |
| <s:TextInput id="fullname" width="200"/> |
| </s:FormItem> |
| |
| <s:FormItem label="Email" required="true"> |
| <s:TextInput id="email" width="200"/> |
| </s:FormItem> |
| |
| <s:FormItem label="Phone" required="true"> |
| <s:TextInput id="phone" width="200"/> |
| </s:FormItem> |
| |
| <s:FormItem label="Zip" required="true"> |
| <s:TextInput id="zip" width="60"/> |
| </s:FormItem> |
| |
| <s:FormItem label="Social Security" required="true"> |
| <s:TextInput id="ssn" width="200"/> |
| </s:FormItem> |
| </s:Form> |
| </s:Application></pre> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff6_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff6_verapache"><!-- --></a> |
| <h3 class="topictitle3">Binding a source property to more |
| than one destination property</h3> |
| |
| |
| <div> |
| <p> |
| You can bind |
| a single source property to more than one destination property by using |
| the curly braces (<samp class="codeph">{}</samp>) syntax, the <a href="mxml/binding.html" target="_blank"><fx:Binding></a> tag, |
| or the <samp class="codeph">BindingUtils</samp>methods in ActionScript. In |
| the following example, a TextInput control’s <samp class="codeph">text</samp> property |
| is bound to properties of two data models, and the data model properties |
| are bound to the <samp class="codeph">text</samp> properties of two Label controls.</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/BindMultDestinations.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"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <fx:Declarations> |
| <fx:Model id="mod1"> |
| <data> |
| <part>{input1.text}</part> |
| </data> |
| </fx:Model> |
| |
| <fx:Model id="mod2"> |
| <data> |
| <part>{input1.text}</part> |
| </data> |
| </fx:Model> |
| </fx:Declarations> |
| |
| <s:TextInput id="input1" text="Hello" /> |
| |
| <s:Label text="{mod1.part}"/> |
| <s:Label text="{mod2.part}"/> |
| </s:Application></pre> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf69084-7cca_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7cca_verapache"><!-- --></a> |
| <h3 class="topictitle3">Binding more than one source property |
| to a destination property</h3> |
| |
| |
| <div> |
| <p>You can bind more than one source property to the same |
| destination property. You can set up one of these bindings by using |
| curly braces, but you must set up the others by using the <samp class="codeph"><fx:Binding></samp> tag, |
| or by using calls to the <samp class="codeph">BindingUtils.bindProperty()</samp> method |
| or to the <samp class="codeph">BindingUtils.bindSetter()</samp> method. </p> |
| |
| <p>In the following example, the TextArea control is the binding |
| destination, and both <samp class="codeph">input1.text</samp> and <samp class="codeph">input2.text</samp> are |
| its binding sources:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/BindMultSources.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"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <fx:Binding source="input2.text" destination="myTA.text"/> |
| |
| <s:TextInput id="input1"/> |
| <s:TextInput id="input2"/> |
| |
| <s:TextArea id="myTA" text="{input1.text}"/> |
| </s:Application></pre> |
| |
| <p>If <samp class="codeph">input1.text</samp> or <samp class="codeph">input2.text</samp> is |
| updated, the TextArea control contains the updated value. </p> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff4_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff4_verapache"><!-- --></a> |
| <h3 class="topictitle3">Defining bidirectional bindings</h3> |
| |
| |
| <div> |
| <p>Bidirectional, or two-way, data binding occurs when two |
| objects act as the source and the destination for each other. When |
| you modify the source property of either object, the destination |
| property of the other object is updated.</p> |
| |
| <p>Define a bidirectional data binding using one of the following |
| methods:</p> |
| |
| <div class="p"> |
| <ol> |
| <li> |
| <p>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: </p> |
| |
| <div class="p"> |
| <pre class="codeblock"><!-- Specify data binding for both controls. --> |
| <s:TextInput id="input1" text="{input2.text}"/> |
| <s:TextInput id="input2" text="{input1.text}"/> </pre> |
| |
| </div> |
| |
| </li> |
| |
| <li> |
| <p>Use the <samp class="codeph">@{bindable_property}</samp> syntax for |
| one source property, as the following example shows:</p> |
| |
| <div class="p"> |
| <pre class="codeblock"><!-- Specify data binding for both controls. --> |
| <s:TextInput id="input1" text="@{input2.text}"/> |
| <s:TextInput id="input2"/></pre> |
| |
| </div> |
| |
| <div class="note"><span class="notetitle">Note:</span> The property |
| definition that includes the <samp class="codeph">@{bindable_property}</samp> syntax |
| is called the <em>primary</em> 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. </div> |
| |
| </li> |
| |
| <li> |
| <p>Use the <samp class="codeph">twoWay</samp> property of the <samp class="codeph"><fx:Binding></samp> tag, |
| as the following example shows:</p> |
| |
| <pre class="codeblock"><fx:Binding source="input1.text" destination="input2.text" twoWay="true"/></pre> |
| |
| <p>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.</p> |
| |
| </li> |
| |
| </ol> |
| |
| </div> |
| |
| <p>The following example shows these three techniques:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/BindBiDirection.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"> |
| <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></pre> |
| |
| <p>In this example, the TextInput controls are the source of a data |
| binding expression, and both are a destination. For example, when |
| you modify input1, its value is copied to input2, and when you modify |
| input2, its value is copied to input1. </p> |
| |
| <p>Flex ensures that bidirectional data bindings do not result in |
| an infinite loop; that is, Flex ensures that a bidirectional data |
| binding is triggered only once when either source property is modified.</p> |
| |
| </div> |
| |
| <div class="nested3" id="WS300C7817-C65B-42cd-A485-8C5CF13E8002_verapache"><a name="WS300C7817-C65B-42cd-A485-8C5CF13E8002_verapache"><!-- --></a> |
| <h4 class="topictitle4">Restrictions on where you can use |
| bidirectional data binding</h4> |
| |
| |
| <div> |
| <div class="p">Bidirectional data bindable is supported in most places |
| in an application. However, the following table shows where bidirectional |
| data binding is not supported: |
| <div class="tablenoborder"><table cellpadding="4" cellspacing="0" summary="" frame="border" border="1" rules="all"> |
| |
| |
| <thead align="left"> |
| <tr> |
| <th class="cellrowborder" valign="top" width="NaN%" id="d168453e698"> |
| <p>Expression</p> |
| |
| </th> |
| |
| <th class="cellrowborder" valign="top" width="NaN%" id="d168453e704"> |
| <p>Bidirectional Binding Supported</p> |
| |
| </th> |
| |
| </tr> |
| |
| </thead> |
| |
| <tbody> |
| <tr> |
| <td class="cellrowborder" valign="top" width="NaN%" headers="d168453e698 "> |
| <p>Style properties</p> |
| |
| </td> |
| |
| <td class="cellrowborder" valign="top" width="NaN%" headers="d168453e704 "> |
| <p>No</p> |
| |
| </td> |
| |
| </tr> |
| |
| <tr> |
| <td class="cellrowborder" valign="top" width="NaN%" headers="d168453e698 "> |
| <p>Effect properties</p> |
| |
| </td> |
| |
| <td class="cellrowborder" valign="top" width="NaN%" headers="d168453e704 "> |
| <p>No</p> |
| |
| </td> |
| |
| </tr> |
| |
| <tr> |
| <td class="cellrowborder" valign="top" width="NaN%" headers="d168453e698 "> |
| <p>The <samp class="codeph">request</samp> property of |
| the HttpService, RemoteObject, and WebService classes.</p> |
| |
| </td> |
| |
| <td class="cellrowborder" valign="top" width="NaN%" headers="d168453e704 "> |
| <p>No</p> |
| |
| </td> |
| |
| </tr> |
| |
| <tr> |
| <td class="cellrowborder" valign="top" width="NaN%" headers="d168453e698 "> |
| <p>The <samp class="codeph">arguments</samp> property |
| of the RemoteObject class.</p> |
| |
| </td> |
| |
| <td class="cellrowborder" valign="top" width="NaN%" headers="d168453e704 "> |
| <p>No</p> |
| |
| </td> |
| |
| </tr> |
| |
| </tbody> |
| |
| </table> |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested3" id="WS15383DD9-57E7-420c-9E78-FB715D091976_verapache"><a name="WS15383DD9-57E7-420c-9E78-FB715D091976_verapache"><!-- --></a> |
| <h4 class="topictitle4">Binding compatibility with Flex |
| 3</h4> |
| |
| |
| <div> |
| <div class="p">In Flex 3, the following binding expression was interpreted |
| as a one-way binding:<pre class="codeblock"><mx:String id="str">test</mx:String> |
| <mx:Text text="@{str}"/></pre> |
| |
| </div> |
| |
| <p>Flex 3 set the Text component’s <samp class="codeph">text</samp> property |
| to “test”, but the value of the String component did not change |
| if the Text component’s <samp class="codeph">text</samp> property changed.</p> |
| |
| <p>In Flex 4 and later, this code is interpreted as a bidirectional |
| data binding expression. A change in the String component updates |
| the <samp class="codeph">text</samp> property of the Text component, and a |
| change in the <samp class="codeph">text</samp> property of the Text component updates |
| the String component. You can prevent the compiler from enforcing |
| the bidirectional binding by setting the value of the <samp class="codeph">compatibility-version</samp> compiler |
| option to <samp class="codeph">3.0.0</samp>, as the following example shows:</p> |
| |
| <pre class="codeblock">mxmlc ... -compatibility-version=3.0.0 ...</pre> |
| |
| <p>For more information, see <a href="flx_versioning_ve.html#WS2db454920e96a9e51e63e3d11c0bf69084-7ede_verapache">Backward |
| compatibility</a>.</p> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested1" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff3_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff3_verapache"><!-- --></a> |
| <h2 class="topictitle2">Binding to functions, Objects, |
| and Arrays </h2> |
| |
| |
| <div> |
| <p/> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff2_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff2_verapache"><!-- --></a> |
| <h3 class="topictitle3">Using functions as the source for |
| a data binding</h3> |
| |
| |
| <div> |
| <p>You can use a function as part of the source of a data |
| binding expression. 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. </p> |
| |
| <div class="section" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff2_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff1_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff2_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff1_verapache"><!-- --></a><h4 class="sectiontitle">Using |
| functions that take bindable properties as arguments</h4> |
| |
| <p>You |
| can use ActionScript functions as the source of data binding expressions when |
| using a bindable property as an argument of the function. When the bindable |
| property changes, the function executes, and the result is written |
| to the destination property, as the following example shows:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/ASInBraces.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"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <fx:Declarations> |
| <s:CurrencyFormatter id="usdFormatter" useCurrencySymbol="true"/> |
| </fx:Declarations> |
| |
| <s:TextInput id="myTI" text="Enter number here"/> |
| <s:TextArea text="{usdFormatter.format(myTI.text)}"/> |
| </s:Application></pre> |
| |
| <p>In this example, Flex calls |
| the <samp class="codeph">CurrencyFormatter.format()</samp> method to update |
| the TextArea control every time the <samp class="codeph">text</samp> property |
| of the TextInput control is modified. </p> |
| |
| <p>If the function is |
| not passed an argument that can be used as the source of a data binding |
| expression, the function only gets called once when the applications starts. </p> |
| |
| </div> |
| |
| <div class="section" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff2_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff0_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff2_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7ff0_verapache"><!-- --></a><h4 class="sectiontitle">Binding |
| to functions in response to a data-binding event</h4> |
| |
| <p>You can |
| specify a function that takes no bindable arguments as the source |
| of a data binding expression. However, you then need a way to invoke |
| the function to update the destination of the data binding. </p> |
| |
| <p>In |
| the following example, you use the <samp class="codeph">[Bindable]</samp> metadata |
| tag to specify to Flex to invoke the <samp class="codeph">isEnabled()</samp>function |
| in response to the event <samp class="codeph">myFlagChanged</samp>. When the |
| myFlag setter gets called, it dispatches the <samp class="codeph">myFlagChanged</samp> event |
| to trigger any data bindings that use the <samp class="codeph">isEnabled()</samp>function |
| as the source: </p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/ASFunction.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"> |
| <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></pre> |
| |
| <p>For more information on the <samp class="codeph">[Bindable]</samp> metadata |
| tag, see <a href="flx_databinding_db.html#WS2db454920e96a9e51e63e3d11c0bf69084-7cc5_verapache">Using |
| the Bindable metadata tag</a>.</p> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fef_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fef_verapache"><!-- --></a> |
| <h3 class="topictitle3">Using data binding with Objects</h3> |
| |
| |
| <div> |
| <p>When working with Objects, you have to consider when you |
| define a binding to the Object, or when you define a binding to |
| a property of the Object. </p> |
| |
| <div class="section" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fef_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7fee_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fef_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7fee_verapache"><!-- --></a><h4 class="sectiontitle">Binding |
| to Objects</h4> |
| |
| <p>When you make an Object the source of a data |
| binding expression, the data binding occurs when the Object is updated, |
| or when a reference to the Object is updated, but not when an individual |
| field of the Object is updated.</p> |
| |
| <p>In the following example, |
| you create subclass of Object that defines two properties, <samp class="codeph">stringProp</samp> and <samp class="codeph">intProp</samp>, |
| but does not make the properties bindable:</p> |
| |
| <pre class="codeblock">package myComponents |
| { |
| // binding/myComponents/NonBindableObject.as |
| |
| // Make no class properties bindable. |
| public class NonBindableObject extends Object { |
| |
| public function NonBindableObject() { |
| super(); |
| } |
| |
| public var stringProp:String = "String property"; |
| |
| public var intProp:int = 52; |
| } |
| }</pre> |
| |
| <p>Since the properties of the class are not bindable, |
| Flex will not dispatch an event when they are updated to trigger |
| data binding. You then use this class in a Flex application, as |
| the following example shows:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- 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></pre> |
| |
| <p>Because you did not make the |
| individual fields of the NonBindableObject class bindable, the data |
| bindings for the two Text controls are updated at application start |
| up, and when myObj is updated, but not when the individual properties |
| of myObj are updated. </p> |
| |
| <p>When you compile the application, the |
| compiler outputs warning messages stating that the data binding |
| mechanism will not be able to detect changes to stringProp and intProp.</p> |
| |
| </div> |
| |
| <div class="section" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fef_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7fed_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fef_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7fed_verapache"><!-- --></a><h4 class="sectiontitle">Binding |
| to properties of Objects</h4> |
| |
| <p>To make properties of an Object |
| bindable, you create a new class definition for the Object, as the |
| following example shows:</p> |
| |
| <pre class="codeblock">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; |
| } |
| }</pre> |
| |
| <p>By placing the <samp class="codeph">[Bindable]</samp> metadata |
| tag before the class definition, you make bindable all public properties |
| defined as variables, and all public properties defined by using |
| both a setter and a getter method. You can then use the stringProp |
| and intProp properties as the source for a data binding, as the following |
| example shows:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/SimpleObjectBinding.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.BindableObject; |
| |
| [Bindable] |
| public var myObj:BindableObject = new BindableObject(); |
| |
| [Bindable] |
| public var anotherObj:BindableObject = |
| new BindableObject(); |
| |
| 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 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;"/> |
| </s:Application></pre> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fec_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fec_verapache"><!-- --></a> |
| <h3 class="topictitle3">Binding with arrays</h3> |
| |
| |
| <div> |
| <p>When working with arrays, such as Array or ArrayCollection |
| objects, you can define the array as the source or destination of |
| a data binding expression. </p> |
| |
| <div class="note"><span class="notetitle">Note:</span> 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 <samp class="codeph">ArrayCollection.addItem()</samp>, <samp class="codeph">ArrayCollection.addItemAt()</samp>, <samp class="codeph">ArrayCollection.removeItem()</samp>, |
| and <samp class="codeph">ArrayCollection.removeItemAt()</samp> all trigger |
| data binding.</div> |
| |
| <div class="section" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fec_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7feb_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fec_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7feb_verapache"><!-- --></a><h4 class="sectiontitle">Binding |
| to arrays</h4> |
| |
| <p>You often bind arrays to the <samp class="codeph">dataProvider</samp> property |
| of Flex controls, as the following example shows for the List control:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/ArrayBindingDP.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"> |
| <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, |
| 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');"/> |
| |
| <!-- Data bindings to myAC updated. --> |
| <s:Button |
| label="Remove Element 0" |
| click="myAC.removeItemAt(0);"/> |
| |
| <!-- Data bindings to myAC updated. --> |
| <s:Button |
| label="Change ArrayCollection" |
| click="myAC=myAC2"/> |
| </s:Application></pre> |
| |
| <p>This example defines an ArrayCollection |
| object, and then uses data binding to set the data provider of the |
| List control to the ArrayCollection. When you modify an element |
| of the ArrayCollection object, or when you modify a reference to |
| the ArrayCollection object, you trigger a data binding. </p> |
| |
| </div> |
| |
| <div class="section" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fec_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7fea_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fec_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7fea_verapache"><!-- --></a><h4 class="sectiontitle">Binding |
| to array elements</h4> |
| |
| <p>You can use individual ArrayCollection |
| elements as the source or a binding expression, as the following |
| example shows:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/ArrayBinding.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"> |
| <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></pre> |
| |
| <p>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.</p> |
| |
| <p>However, |
| the data binding expression <samp class="codeph">myAC.getItemAt(0)</samp> is |
| triggered when an array element changes. Therefore, the text2 Text |
| control is updated when you click button1, while text1 is not. When |
| using an array element as the source of a data binding expression, |
| you should use the <samp class="codeph">ArrayCollection.getItemAt()</samp> method |
| in the binding expression. </p> |
| |
| <p>Clicking button2 copies myAC2 |
| to myAC, and triggers all data bindings to array elements regardless |
| of how you implemented them. </p> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested1" id="WS2db454920e96a9e51e63e3d11c0bf69084-7ccc_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7ccc_verapache"><!-- --></a> |
| <h2 class="topictitle2">Using ActionScript in data binding expressions</h2> |
| |
| |
| <div> |
| <p>You can use ActionScript in data binding expressions defined |
| by curly braces and by the <samp class="codeph"><fx:Binding></samp> tag; |
| however, you cannot use ActionScript when defining a data binding |
| by using the <samp class="codeph">BindingUtils.bindProperty()</samp> or the <samp class="codeph">BindingUtils.bindSetter()</samp> method.</p> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fe8_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fe8_verapache"><!-- --></a> |
| <h3 class="topictitle3">Using ActionScript expressions |
| in curly braces</h3> |
| |
| |
| <div> |
| <p>Binding expressions in curly braces can contain an ActionScript |
| expression that returns a value. For example, you can use the curly |
| braces syntax for the following types of binding.</p> |
| |
| <ul> |
| <li> |
| <p>A single bindable property inside curly braces</p> |
| |
| </li> |
| |
| <li> |
| <p>To cast the data type of the source property to a type that |
| matches the destination property</p> |
| |
| </li> |
| |
| <li> |
| <p>String concatenation that includes a bindable property inside |
| curly braces</p> |
| |
| </li> |
| |
| <li> |
| <p>Calculations on a bindable property inside curly braces</p> |
| |
| </li> |
| |
| <li> |
| <p>Conditional operations that evaluate a bindable property |
| value</p> |
| |
| </li> |
| |
| </ul> |
| |
| <p>The following example shows a data model that uses each type |
| of binding expression:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/AsInBinding.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"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <fx:Declarations> |
| <fx:Model id="myModel"> |
| <myModel> |
| <!-- Perform simple property binding. --> |
| <a>{nameInput.text}</a> |
| <!-- Perform string concatenation. --> |
| <b>This is {nameInput.text}</b> |
| <!-- Perform a calculation. --> |
| <c>{(Number(numberInput.text)) * 6 / 7}</c> |
| <!-- Perform a conditional operation using a ternary operator. --> |
| <d>{(isMale.selected) ? "Mr." : "Ms."} {nameInput.text}</d> |
| </myModel> |
| </fx:Model> |
| </fx:Declarations> |
| |
| <s:Form> |
| <s:FormItem label="Last Name:"> |
| <s:TextInput id="nameInput"/> |
| </s:FormItem> |
| <s:FormItem label="Select sex:"> |
| <s:RadioButton id="isMale" |
| label="Male" |
| groupName="gender" |
| selected="true"/> |
| <s:RadioButton id="isFemale" |
| label="Female" |
| groupName="gender"/> |
| </s:FormItem> |
| <s:FormItem label="Enter a number:"> |
| <s:TextInput id="numberInput" text="0"/> |
| </s:FormItem> |
| </s:Form> |
| |
| <s:Label |
| text="{'Calculation: '+numberInput.text+' * 6 / 7 = '+myModel.c}"/> |
| <s:Label text="{'Conditional: '+myModel.d}"/> |
| </s:Application></pre> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fe7_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fe7_verapache"><!-- --></a> |
| <h3 class="topictitle3">Using ActionScript expressions |
| in Binding tags</h3> |
| |
| |
| <div> |
| <p>The <samp class="codeph">source</samp> property of an <samp class="codeph"><fx:Binding></samp> tag |
| can contain curly braces. When there are no curly braces in the <samp class="codeph">source</samp> property, |
| the value is treated as a single ActionScript expression. When there |
| are curly braces in the <samp class="codeph">source</samp> property, the value |
| is treated as a concatenated ActionScript expression. The <samp class="codeph"><fx:Binding></samp> tags |
| in the following example are valid and equivalent to each other:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/ASInBindingTags.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"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <fx:Script> |
| <![CDATA[ |
| public function whatDogAte():String { |
| return "homework"; |
| } |
| ]]> |
| </fx:Script> |
| |
| <fx:Binding |
| source="'The dog ate my '+ whatDogAte()" |
| destination="field1.text"/> |
| <fx:Binding |
| source="{'The dog ate my '+ whatDogAte()}" |
| destination="field2.text"/> |
| <fx:Binding |
| source="The dog ate my {whatDogAte()}" |
| destination="field3.text"/> |
| |
| <s:TextArea id="field1"/> |
| <s:TextArea id="field2"/> |
| <s:TextArea id="field3"/> |
| </s:Application></pre> |
| |
| <p>The <samp class="codeph">source</samp> property in the following example |
| is not valid because it is not an ActionScript expression:</p> |
| |
| <pre class="codeblock"> <fx:Binding source="The dog ate my homework" destination="field1.text"/></pre> |
| |
| </div> |
| |
| <div class="nested3" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fe6_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fe6_verapache"><!-- --></a> |
| <h4 class="topictitle4">Using an ampersand character in |
| a data binding expression</h4> |
| |
| |
| <div> |
| <p>Because of the parsing rules of XML, if you want to use |
| an ampersand character, <samp class="codeph">&</samp>, in a data binding |
| expression in an MXML file, you must replace it with the hexadecimal |
| equivalent character, <samp class="codeph">&amp;</samp>. For example, if |
| you want to use a logical AND expression, written in ActionScript |
| as <samp class="codeph">&&</samp>, then you have to write is as <samp class="codeph">&amp;&amp;</samp>, |
| as the following example shows:</p> |
| |
| <pre class="codeblock"> <s:Button label="Test" enabled="{authorized <strong>&amp;&amp;</strong> cc}" /> </pre> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested1" id="WS2db454920e96a9e51e63e3d11c0bf69084-7ccb_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7ccb_verapache"><!-- --></a> |
| <h2 class="topictitle2">Using an E4X expression in a data |
| binding expression</h2> |
| |
| |
| <div> |
| <p> |
| |
| A binding expression in curly braces |
| or an <samp class="codeph"><fx:Binding></samp> tag can contain an ECMAScript |
| for XML (E4X) expression when the source of a binding is a bindable property |
| of type XML. You cannot use E4X when defining a data binding by |
| using the <samp class="codeph">BindingUtils.bindProperty()</samp> or the <samp class="codeph">BindingUtils.bindSetter()</samp> method. </p> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fe4_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fe4_verapache"><!-- --></a> |
| <h3 class="topictitle3">Using an E4X expression in curly |
| braces</h3> |
| |
| |
| <div> |
| <p> |
| A binding |
| expression in curly braces automatically calls the <samp class="codeph">toString()</samp> method |
| when the binding destination is a String property. A binding expression in |
| curly braces or an <samp class="codeph"><fx:Binding></samp> tag can contain |
| an ECMAScript for XML (E4X) expression when the source of a binding |
| is a bindable property of type XML; for more information, see <a href="flx_databinding_db.html#WS2db454920e96a9e51e63e3d11c0bf69084-7cc1_verapache">Using |
| an E4X expression in an <fx:Binding> tag</a>.</p> |
| |
| <p>In the code in the following example, there are three binding |
| expressions in curly braces that bind data from an XML object. The |
| first uses . (dot) notation, the second uses .. (dot dot) notation, |
| and the third uses || (or) notation.</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/E4XInBraces.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" |
| width="750"> |
| <s:layout> |
| <s:HorizontalLayout/> |
| </s:layout> |
| |
| <fx:Script> |
| <![CDATA[ |
| |
| [Bindable] |
| public var xdata:XML = <order> |
| <item id = "3456"> |
| <description>Big Screen Television</description> |
| <price>1299.99</price><quantity>1</quantity> |
| </item> |
| <item id = "56789"> |
| <description>DVD Player</description> |
| <price>399.99</price> |
| <quantity>1</quantity> |
| </item> |
| </order>; |
| ]]> |
| </fx:Script> |
| |
| <mx:Label text="Using .. notation."/> |
| <!-- Inline databinding will automatically call the |
| toString() method when the binding destination is a string. --> |
| <mx:List width="25%" |
| dataProvider="{xdata..description}"/> |
| |
| <mx:Label text="Using . notation."/> |
| <mx:List width="25%" |
| dataProvider="{xdata.item.description}"/> |
| |
| <mx:Label text="Using || (or) notation."/> |
| <mx:List width="25%" |
| dataProvider="{xdata.item.(@id=='3456'||@id=='56789').description}"/> |
| </s:Application></pre> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf69084-7cc1_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7cc1_verapache"><!-- --></a> |
| <h3 class="topictitle3">Using an E4X expression in an <fx:Binding> |
| tag</h3> |
| |
| |
| <div> |
| <p>Unlike an E4X expression in curly braces, when you use |
| an E4X expression in an <samp class="codeph"><fx:Binding></samp> tag, |
| you must explicitly call the <samp class="codeph">toString()</samp> method |
| when the binding destination is a String property.</p> |
| |
| <p>In the code in the following example, there are three binding |
| expressions in curly braces that bind data from an XML object. The |
| first uses . (dot) notation, the second uses .. (dot dot) notation, |
| and the third uses || (or) notation.</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/E4XInBindingTag.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" |
| width="600" height="900"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <fx:Script> |
| <![CDATA[ |
| [Bindable] |
| public var xdata:XML = |
| <order> |
| <item id = "3456"> |
| <description>Big Screen Television</description> |
| <price>1299.99</price><quantity>1</quantity> |
| </item> |
| <item id = "56789"> |
| <description>DVD Player</description> |
| <price>399.99</price> |
| <quantity>1</quantity> |
| </item> |
| </order>; |
| ]]> |
| </fx:Script> |
| |
| <mx:Label text="Using .. notation."/> |
| |
| <!-- This will update because what is |
| binded is actually the String and XMLList. --> |
| <mx:List width="75%" id="txts"/> |
| |
| <mx:Label text="Using . notation."/> |
| <mx:List width="75%" id="txt2s"/> |
| |
| <mx:Label text="Using || (or) notation."/> |
| <mx:List width="75%" id="txt3s"/> |
| |
| <fx:Binding |
| source="xdata..description" |
| destination="txts.dataProvider"/> |
| <fx:Binding |
| source="xdata.item.description" |
| destination="txt2s.dataProvider"/> |
| <fx:Binding |
| source="xdata.item.(@id=='3456'||@id=='56789').description" |
| destination="txt3s.dataProvider"/> |
| </s:Application></pre> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested1" id="WS2db454920e96a9e51e63e3d11c0bf69084-7cc9_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7cc9_verapache"><!-- --></a> |
| <h2 class="topictitle2">Defining data bindings in ActionScript</h2> |
| |
| |
| <div> |
| <p> |
| You |
| can define a data binding in ActionScript by using the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/binding/utils/BindingUtils.html" target="_blank">mx.binding.utils.BindingUtils</a> class. |
| This class defines static methods that let you create a data binding |
| to a property implemented as a variable, by using the <samp class="codeph">bindProperty()</samp> method, |
| or to a method, by using the <samp class="codeph">bindSetter()</samp> method. |
| For an example using the <samp class="codeph">bindProperty()</samp> method, |
| see <a href="flx_databinding_db.html#WS2db454920e96a9e51e63e3d11c0bf64c3d-7fff_verapache">About |
| data binding</a>.</p> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fe1_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fe1_verapache"><!-- --></a> |
| <h3 class="topictitle3">Differences between defining bindings |
| in MXML and ActionScript</h3> |
| |
| |
| <div> |
| <p>There are a few differences between defining data bindings |
| in MXML at compile time and in defining them at runtime in ActionScript:</p> |
| |
| <ul> |
| <li> |
| <p>You cannot include ActionScript code in a data binding |
| expression defined by the <samp class="codeph">bindProperty()</samp> or <samp class="codeph">bindSetter()</samp> method. |
| Instead, use the <samp class="codeph">bindSetter()</samp> method to specify |
| a method to call when the binding occurs.</p> |
| |
| </li> |
| |
| <li> |
| <p>You cannot include an E4X expression in a data binding expression |
| defined in ActionScript. </p> |
| |
| </li> |
| |
| <li> |
| <p>You cannot include functions or array elements in property |
| chains in a data binding expression defined by the <samp class="codeph">bindProperty()</samp> or <samp class="codeph">bindSetter()</samp> method. </p> |
| |
| </li> |
| |
| <li> |
| <p>The MXML compiler has better warning and error detection |
| support than runtime data bindings defined by the <samp class="codeph">bindProperty()</samp> or <samp class="codeph">bindSetter()</samp> method.</p> |
| |
| </li> |
| |
| </ul> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fe0_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fe0_verapache"><!-- --></a> |
| <h3 class="topictitle3">Example: Defining a data binding |
| in ActionScript</h3> |
| |
| |
| <div> |
| <p>The following example uses the <samp class="codeph">bindSetter()</samp> method |
| to set up a data binding. The arguments to the <samp class="codeph">bindSetter()</samp> method |
| specify the following:</p> |
| |
| <ul> |
| <li> |
| <p>The source object</p> |
| |
| </li> |
| |
| <li> |
| <p>The name of the source property</p> |
| |
| </li> |
| |
| <li> |
| <p>A method that is called when the source property changes</p> |
| |
| </li> |
| |
| </ul> |
| |
| <p>In the following example, as you enter text in the TextInput |
| control, the text is converted to upper case as it is copied to |
| the TextArea control:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/BindSetterAS.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"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <fx:Script> |
| <![CDATA[ |
| |
| import mx.binding.utils.*; |
| import mx.events.FlexEvent; |
| |
| // Method called when myTI.text changes. |
| public function updateMyString(val:String):void { |
| myTA.text = val.toUpperCase(); |
| } |
| |
| <!-- Event listener to configure binding. --> |
| public function mySetterBinding(event:FlexEvent):void { |
| var watcherSetter:ChangeWatcher = |
| BindingUtils.bindSetter(updateMyString, myTI, "text"); |
| } |
| ]]> |
| </fx:Script> |
| |
| <s:Label text="Bind Setter using setter method"/> |
| <s:TextInput id="myTI" |
| text="Hello Setter" /> |
| <s:TextArea id="myTA" |
| initialize="mySetterBinding(event);"/> |
| </s:Application></pre> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf69084-7cc7_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7cc7_verapache"><!-- --></a> |
| <h3 class="topictitle3">Defining binding watchers </h3> |
| |
| |
| <div> |
| <p>Flex includes the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/binding/utils/ChangeWatcher.html" target="_blank">mx.binding.utils.ChangeWatcher</a> class |
| that you can use to define a data‑binding watcher. Typically, a |
| data-binding watcher invokes an event listener when a binding occurs. |
| To set up a data-binding watcher, you use the static <samp class="codeph">watch()</samp> method |
| of the ChangeWatcher class, as the following example shows: </p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/DetectWatcher.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" |
| initialize="initWatcher();"> |
| <s:layout> |
| <s:VerticalLayout/> |
| </s:layout> |
| |
| <fx:Script> |
| <![CDATA[ |
| import mx.binding.utils.*; |
| import mx.events.FlexEvent; |
| import mx.events.PropertyChangeEvent; |
| |
| public var myWatcher:ChangeWatcher; |
| |
| // Define binding watcher. |
| public function initWatcher():void { |
| // Define a watcher for the text binding. |
| myWatcher = ChangeWatcher.watch(textarea, "text", watcherListener); |
| } |
| |
| // Event listener when binding occurs. |
| public function watcherListener(event:Event):void { |
| myTA1.text="binding occurred"; |
| |
| // Use myWatcher.unwatch() to remove the watcher. |
| } |
| ]]> |
| </fx:Script> |
| |
| <!-- Define a binding expression to watch. --> |
| <s:TextInput id="textinput" text="Hello"/> |
| <s:TextArea id="textarea" text="{textinput.text}"/> |
| |
| <!-- Trigger a binding. --> |
| <s:Button label="Submit" click="textinput.text='Goodbye';"/> |
| <s:TextArea id="myTA1"/> |
| </s:Application></pre> |
| |
| <p>You define an event listener for the data-binding watcher, where |
| the event listener takes a single argument that contains the event |
| object. The data type of the event object is determined by the property |
| being watched. Each bindable property can dispatch a different event |
| type and the associated event object. For more information on determining |
| the event type, see <a href="flx_databinding_db.html#WS2db454920e96a9e51e63e3d11c0bf69084-7cc5_verapache">Using |
| the Bindable metadata tag</a>. </p> |
| |
| <p>Many event listeners take an event object of type PropertyChangeEvent |
| because that is the default data type of the event dispatched by |
| bindable properties. You can always specify an event type of flash.events.Event, |
| the base class for all Flex events. </p> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested1" id="WS2db454920e96a9e51e63e3d11c0bf69084-7cc5_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7cc5_verapache"><!-- --></a> |
| <h2 class="topictitle2">Using the Bindable metadata tag</h2> |
| |
| |
| <div> |
| <p>When a property is the source of a data binding expression, |
| Flex automatically copies the value of the source property to any |
| destination property when the source property changes. To signal |
| to Flex to perform the copy, you must use the <samp class="codeph">[Bindable]</samp> metadata |
| tag to register the property with Flex, and the source property |
| must dispatch an event. </p> |
| |
| <p>The <samp class="codeph">[Bindable]</samp> metadata tag has the following |
| syntax:</p> |
| |
| <pre class="codeblock"> [Bindable] |
| [Bindable(event="eventname")]</pre> |
| |
| <p>If you omit the event name, Flex automatically creates an event |
| named <samp class="codeph">propertyChange</samp> of type PropertyChangeEvent.</p> |
| |
| <p>You can use the <samp class="codeph">[Bindable]</samp> metadata tag in three |
| places:</p> |
| |
| <ol> |
| <li> |
| <p>Before a public class definition. </p> |
| |
| <p>The <samp class="codeph">[Bindable]</samp> metadata |
| tag makes usable as the source of a binding expression all public |
| properties that you defined as variables, and all public properties |
| that are defined by using both a setter and a getter method. In |
| this case, <samp class="codeph">[Bindable]</samp> takes no parameters, as the |
| following example shows:</p> |
| |
| <pre class="codeblock"> [Bindable] |
| public class TextAreaFontControl extends TextArea {}</pre> |
| |
| <p>The |
| compiler automatically generates an event named <samp class="codeph">propertyChange</samp>, of |
| type PropertyChangeEvent, for all public properties so that the |
| properties can be used as the source of a data binding expression. </p> |
| |
| <p>If |
| the property value remains the same on a write, Flex does not dispatch |
| the event or update the property, where <em>not the same</em> translates |
| to the following test:</p> |
| |
| <pre class="codeblock"> (oldValue !== value)</pre> |
| |
| <p>That |
| means if a property contains a reference to an object, and that |
| reference is modified to reference a different but equivalent object, |
| the binding is triggered. If the property is not modified, but the |
| object that it points to changes internally, the binding is not |
| triggered.</p> |
| |
| <div class="note"><span class="notetitle">Note:</span> When you use the <samp class="codeph">[Bindable]</samp> metadata |
| tag before a public class definition, it only applies to public |
| properties; it does not apply to private or protected properties, |
| or to properties defined in any other namespace. You must insert |
| the <samp class="codeph">[Bindable]</samp> |
| <em> metadata tag before a nonpublic property to make it usable as the source for a data binding expression.</em> |
| </div> |
| |
| </li> |
| |
| <li> |
| <p>Before a public, protected, or private property defined as |
| a variable to make that specific property support binding. </p> |
| |
| <p>The |
| tag can have the following forms:</p> |
| |
| <pre class="codeblock"> [Bindable] |
| public var foo:String;</pre> |
| |
| <p>The Flex compiler automatically |
| generates an event named <samp class="codeph">propertyChange</samp>, of type |
| PropertyChangeEvent, for the property. If the property value remains |
| the same on a write, Flex does not dispatch the event or update |
| the property. </p> |
| |
| <p>You can also specify the event name, as the |
| following example shows:</p> |
| |
| <pre class="codeblock"> [Bindable(event="fooChanged")] |
| public var foo:String;</pre> |
| |
| <p>In this case, you are responsible |
| for generating and dispatching the event, typically as part of some |
| other method of your class. You can specify a <samp class="codeph">[Bindable]</samp> tag |
| that includes the <samp class="codeph">event</samp> specification if you want |
| to name the event, even when you already specified the <samp class="codeph">[Bindable]</samp> tag |
| at the class level. </p> |
| |
| </li> |
| |
| <li> |
| <p>Before a public, protected, or private property defined by |
| a getter or setter method.</p> |
| |
| <p>You must define both a setter and |
| a getter method to use the <samp class="codeph">[Bindable]</samp> tag with |
| the property. If you define just a setter method, you create a write-only |
| property that you cannot use as the source of a data-binding expression. If |
| you define just a getter method, you create a read-only property |
| that you can use as the source of a data-binding expression without |
| inserting the <samp class="codeph">[Bindable] </samp>metadata tag. This is |
| similar to the way that you can use a variable, defined by using |
| the <samp class="codeph">const</samp> keyword, as the source for a data binding |
| expression. </p> |
| |
| <p>The tag can have the following forms:</p> |
| |
| <pre class="codeblock"> [Bindable] |
| public function set shortNames(val:Boolean):void { |
| ... |
| } |
| |
| public function get shortNames():Boolean { |
| ... |
| } </pre> |
| |
| <p>The Flex compiler automatically generates an event |
| named <samp class="codeph">propertyChange</samp>, of type PropertyChangeEvent, |
| for the property. If the property value remains the same on a write, |
| Flex does not dispatch the event or update the property. To determine |
| if the property value changes, Flex calls the getter method to obtain |
| the current value of the property. </p> |
| |
| <p>You can specify the event |
| name, as the following example shows:</p> |
| |
| <pre class="codeblock"> [Bindable(event="changeShortNames")] |
| public function set shortNames(val:Boolean):void { |
| ... |
| <strong>// Create and dispatch event. </strong> |
| <strong>dispatchEvent(new Event("changeShortNames"));</strong> |
| } |
| |
| <strong>// Get method. </strong> |
| public function get shortNames():Boolean { |
| ... |
| } </pre> |
| |
| <p>In this case, you are responsible for generating |
| and dispatching the event, typically in the setter method, and Flex |
| does not check to see if the old value and the new value are different. |
| You can specify a <samp class="codeph">[Bindable]</samp> tag that includes |
| the <samp class="codeph">event</samp> specification to name the event, even |
| when you already specified the <samp class="codeph">[Bindable]</samp> tag at |
| the class level. </p> |
| |
| </li> |
| |
| </ol> |
| |
| <p>The following example makes the <samp class="codeph">maxFontSize</samp> and <samp class="codeph">minFontSize</samp> properties |
| that you defined as variables that can be used as the sources for |
| data bindings:</p> |
| |
| <pre class="codeblock"> // Define public vars for tracking font size. |
| [Bindable] |
| public var maxFontSize:Number = 15; |
| [Bindable] |
| public var minFontSize:Number = 5;</pre> |
| |
| <p>In the following example, you make a public property that you |
| defined by using a setter and a getter method that is usable as |
| the source for data binding The <samp class="codeph">[Bindable]</samp> metadata |
| tag includes the name of the event broadcast by the setter method |
| when the property changes:</p> |
| |
| <pre class="codeblock"> // Define private variable. |
| private var _maxFontSize:Number = 15; |
| |
| <strong>[Bindable(event="maxFontSizeChanged")]</strong> |
| // Define public getter method. |
| <strong>public function get maxFontSize():Number {</strong> |
| return _maxFontSize; |
| } |
| |
| <strong>// Define public setter method.</strong> |
| <strong>public function set maxFontSize(value:Number):void {</strong> |
| if (value <= 30) { |
| _maxFontSize = value; |
| } else _maxFontSize = 30; |
| |
| // Create event object. |
| <strong>var eventObj:Event = new Event("maxFontSizeChanged");</strong> |
| <strong>dispatchEvent(eventObj);</strong> |
| |
| }</pre> |
| |
| <p>In this example, the setter updates the value of the property, |
| and then creates and dispatches an event to invoke an update of |
| the destination of the data binding. </p> |
| |
| <p>In an MXML file, you can make all public properties that you |
| defined as variables usable as the source for data binding by including |
| the <samp class="codeph">[Bindable]</samp> metadata tag in an <samp class="codeph"><fx:Metadata></samp> block, |
| as the following example shows: </p> |
| |
| <pre class="codeblock"> <fx:Metadata> |
| [Bindable] |
| </fx:Metadata></pre> |
| |
| <p>You can also use the <samp class="codeph">[Bindable]</samp> metadata tag |
| in an <samp class="codeph"><fx:Script></samp> block in an MXML file to |
| make individual properties that you defined as variables usable as |
| the source for a data binding expression. Alternatively, you can |
| use the <samp class="codeph">[Bindable]</samp> metadata tag with properties |
| that you defined by using setter and getter methods. </p> |
| |
| <div class="section" id="WS2db454920e96a9e51e63e3d11c0bf69084-7cc5_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7fdd_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7cc5_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7fdd_verapache"><!-- --></a><h3 class="sectiontitle">Using |
| read-only properties as the source for data binding</h3> |
| |
| <p>You |
| can automatically use a read-only property defined by a getter method, which |
| means no setter method, as the source for a data-binding expression. |
| Flex performs the data binding once when the application starts. </p> |
| |
| <p>Because |
| the data binding from a read-only property occurs only once at application |
| start up, you omit the <samp class="codeph">[Bindable]</samp> metadata tag |
| for the read-only property.</p> |
| |
| </div> |
| |
| <div class="section" id="WS2db454920e96a9e51e63e3d11c0bf69084-7cc5_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7fdc_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7cc5_verapache__WS2db454920e96a9e51e63e3d11c0bf64c3d-7fdc_verapache"><!-- --></a><h3 class="sectiontitle">Using |
| static properties as the source for data binding</h3> |
| |
| <p>You can |
| use a static variable as the source for a data-binding expression. |
| Flex performs the data binding once when the application starts, |
| and again when the property changes. </p> |
| |
| <p>You can automatically |
| use a static constant as the source for a data-binding expression. |
| Flex performs the data binding once when the application starts. Because |
| the data binding occurs only once at application start up, you omit |
| the <samp class="codeph">[Bindable]</samp> metadata tag for the static constant. |
| The following example uses a static constant as the source for a |
| data-binding expression:</p> |
| |
| <pre class="codeblock"><?xml version="1.0"?> |
| <!-- binding/StaticBinding.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"> |
| |
| <fx:Script> |
| <![CDATA[ |
| |
| // This syntax casues a compiler error. |
| // [Bindable] |
| // public static var varString:String="A static var."; |
| |
| public static const constString:String="A static const."; |
| ]]> |
| </fx:Script> |
| |
| <!-- This binding occurs once at application startup. --> |
| <s:Button label="{constString}"/> |
| </s:Application></pre> |
| |
| </div> |
| |
| <div class="section" id="WS2db454920e96a9e51e63e3d11c0bf69084-7cc5_verapache__WS2db454920e96a9e51e63e3d11c0bf69084-7cbf_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf69084-7cc5_verapache__WS2db454920e96a9e51e63e3d11c0bf69084-7cbf_verapache"><!-- --></a><h3 class="sectiontitle">Working |
| with bindable property chains</h3> |
| |
| <p>When you specify a property |
| as the source of a data binding expression, Flex monitors not only |
| that property for changes, but also the chain of properties leading |
| up to it. The entire chain of properties, including the source property, |
| is called a <em>bindable property chain</em>. In the following example, <samp class="codeph">firstName.text</samp> is a |
| bindable property chain that includes both a <samp class="codeph">firstName</samp> object |
| and its <samp class="codeph">text</samp> property:</p> |
| |
| <pre class="codeblock"> <s:Label id="myText" text="{firstName.text}"/></pre> |
| |
| <p>You |
| can have a fairly long bindable property chain, as the following |
| example shows:</p> |
| |
| <pre class="codeblock"> <s:Label id="myText" text="{user.name.firstName.text}"/></pre> |
| |
| <p>For |
| the data binding mechanism to detect changes to the <samp class="codeph">text</samp> property, |
| only the <samp class="codeph">text</samp> property has to be bindable. However, |
| if you want to assign a new value to any part of the chain at runtime, |
| every element in the chain must be bindable. Otherwise, modifying |
| the <samp class="codeph">user</samp>, <samp class="codeph">name</samp>, or <samp class="codeph">firstName</samp> property |
| at runtime results in the data binding mechanism no longer being |
| able to detect changes to the <samp class="codeph">text</samp> property. </p> |
| |
| <p>When |
| using the <samp class="codeph">BindingUtils.bindProperty()</samp> or <samp class="codeph">BindingUtils.bindSetter()</samp> method, |
| you specify the bindable property chain as an argument to the method. |
| For example, the <samp class="codeph">bindProperty()</samp> method has the |
| following signature:</p> |
| |
| <pre class="codeblock"> public static function bindProperty(<em>site</em>:Object, <em>prop</em>:String, <em>host</em>:Object, <em>chain</em>:Object, |
| <em>commitOnly</em>:Boolean = false):ChangeWatcher</pre> |
| |
| <p>The <samp class="codeph"> |
| <em>host</em> |
| </samp> and <samp class="codeph"> |
| <em>chain</em> |
| </samp> arguments |
| specify the source of the data binding expression. You can define |
| a data binding expression by using the <samp class="codeph">bindProperty()</samp> method, |
| as the following example shows:</p> |
| |
| <pre class="codeblock"> bindProperty(myText, ’text’, user, ["name","firstName","text"]);</pre> |
| |
| <p>In |
| this example, <samp class="codeph">["name","firstName","text"]</samp> defines |
| the bindable property chain relative to the user object. Notice |
| that <samp class="codeph">user</samp> is not part of the bindable property |
| change in this example. </p> |
| |
| <p>In an MXML data-binding expression, |
| the bindable property chain is always relative to <samp class="codeph">this</samp>. |
| Therefore, to define a data binding equivalent to the MXML data |
| binding expression shown above, you write the <samp class="codeph">bindProperty()</samp> method |
| as the following example shows:</p> |
| |
| <pre class="codeblock"> bindProperty(myText, ’text’, this, ["user", "name","firstName","text"]);</pre> |
| |
| </div> |
| |
| </div> |
| |
| </div> |
| |
| <div class="nested1" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fda_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fda_verapache"><!-- --></a> |
| <h2 class="topictitle2">Considerations for using the binding feature</h2> |
| |
| |
| <div> |
| <p>Consider the following when using the binding feature:</p> |
| |
| <ul> |
| <li> |
| <div class="p">You cannot bind to style properties, but you can bind |
| to the <samp class="codeph">getStyle()</samp> method, as the following example |
| shows:<pre class="codeblock"><s:Button label="Button 1" id="b1" color="green"/> |
| <s:Button label="Button 2" color="{b1.getStyle('color')}"/> |
| <s:Button label="Button 3" click="b1.setStyle('color', 'red');"/></pre> |
| |
| </div> |
| |
| <p>In |
| this example, Button 2 uses data binding to set its <samp class="codeph">color</samp> style |
| property to the same value as the <samp class="codeph">color</samp> style of |
| Button 1.</p> |
| |
| </li> |
| |
| <li> |
| <p>If you bind a model into the <samp class="codeph">dataProvider</samp> property |
| of a component, you should not change items in the model directly. |
| Instead, change the items through the Collections API. Otherwise, |
| the component to which the model is bound is not redrawn to show |
| the changes to the model. For example, instead of using the following:</p> |
| |
| <pre class="codeblock"> myGrid.getItemAt(itemIndex).myField = 1; </pre> |
| |
| <p>You |
| would use the following:</p> |
| |
| <pre class="codeblock"> myGrid.dataProvider.editField(itemIndex, "myField", 1);</pre> |
| |
| </li> |
| |
| <li> |
| <p>Array elements cannot function as binding sources at run |
| time. Arrays that are bound do not stay updated if individual fields |
| of a source Array change. Binding copies values during instantiation |
| after variables are declared in an <samp class="codeph"><fx:Script></samp> tag, |
| but before event listeners execute. </p> |
| |
| </li> |
| |
| </ul> |
| |
| </div> |
| |
| <div class="nested2" id="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fd9_verapache"><a name="WS2db454920e96a9e51e63e3d11c0bf64c3d-7fd9_verapache"><!-- --></a> |
| <h3 class="topictitle3">Debugging data binding</h3> |
| |
| |
| <div> |
| <p> |
| In |
| some situations, data binding may not appear to function correctly, |
| and you may need to debug them. The following list contains suggestions |
| for resolving data binding issues:</p> |
| |
| <ol> |
| <li> |
| <p>Pay attention to warnings. </p> |
| |
| <p>It is easy to see a |
| warning and think that it doesn’t matter, especially if binding appears |
| to work at startup, but warnings are important.</p> |
| |
| <p>If a warning |
| is about a missing <samp class="codeph">[Bindable]</samp> on a getter/setter |
| property, even if the binding works at startup, subsequent changes |
| to the property are not noticed.</p> |
| |
| <p>If a warning is about a static |
| variable or a built-in property, changes aren’t noticed.</p> |
| |
| </li> |
| |
| <li> |
| <p>Ensure that the source of the binding actually changed.</p> |
| |
| <p>When |
| your source is part of a larger procedure, it is easy to miss the |
| fact that you never assigned the source. </p> |
| |
| </li> |
| |
| <li> |
| <p>Ensure that the bindable event is being dispatched.</p> |
| |
| <p>You |
| can use the Flex command-line debugger (fdb) to make sure that the <samp class="codeph">dispatchEvent()</samp> method |
| is called. Also, you can add a normal event listener to that class |
| to make sure it gets called. If you want to add the event listener |
| as a tag attribute, you must place the <samp class="codeph">[Event('</samp> |
| <em>myEvent</em> |
| <samp class="codeph">')]</samp> metadata |
| at the top of your class definition or in an <samp class="codeph"><fx:Metadata></samp> tag |
| in your MXML. </p> |
| |
| </li> |
| |
| <li> |
| <p>Create a setter function and use a <samp class="codeph"><fx:Binding></samp> tag |
| to assign into it.</p> |
| |
| <p>You can then put a trace or an alert or |
| some other debugging code in the setter with the value that is being |
| assigned. This technique ensures that the binding itself is working. |
| If the setter is called with the right information, you will know that |
| it’s your destination that is failing, and you can start debugging |
| there. </p> |
| |
| </li> |
| |
| </ol> |
| |
| <p/> |
| |
| </div> |
| |
| </div> |
| |
| <p>Adobe and Adobe Flash are either registered trademarks or trademarks of Adobe Systems Incorporated in the United States and/or other countries and are used by permission from Adobe. No other license to the Adobe trademarks are granted.</p> |
| </div> |
| |
| |
| </body> |
| </html> |