Flex Data Binding Pitfalls and Common Misuse Mistakes
1. Using [Bindable] When Binding Is Not Necessary
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations> <fx:Script> <![CDATA[ private var text:String = "Hello, World"; ]]> </fx:Script> <s:VGroup> <!-- Bad Practice: <s:TextInput text="{text}"/> --> <s:TextInput id="textInput" text="Hello, World"/> </s:VGroup> </s:Application>
Comment:
1) In the bad practice, the mxmlc still generates code allow binding as this is a one-time assignment.
2) In good practice, we do direct assignment and we can change the text by refering to its id property.
2. Using the Wrong Bindable Event Name
public static const EVENT_CHANGED_CONST:String = "eventChangedConst"; private var _number:Number = 0; [Bindable(event=EVENT_CHANGED_CONST)] public function get number():Number { return _number; } public function set number(value:Number) : void { _number = value; dispatchEvent(new Event(EVENT_CHANGED_CONST)); }
Comment:
1) Assigning a static property to the event name. But when the number changes the binding tag doesn't recognize the change. The reason is the the event name will be EVENT_CHANGED_CONST and not the value of the variable.
3. Assuming Execution Order of Binding
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="1024" minHeight="768" creationComplete="creationCompleteHandler(event)"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; [Bindable] public var buttonText:String = "Execution order mistake "; ]]> </fx:Script> <s:layout> <s:HorizontalLayout /> </s:layout> <s:Label id="simpleText" text="{buttonText}" /> <s:Button label="{simpleText.text}" /> </s:Application>
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="1024" minHeight="768"> <s:TextInput id="textInput1" x="10" y="0" /> <s:TextInput id="textInput2" x="0" y="{textInput1.x+25}" /> </s:Application>
Comment:
1) Never assuming that binding order is in synchronous execution order!
4. Assigning a Binding Tag When You Don't Need It
1)Bad Practice
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="1024" minHeight="768"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; [Bindable] public var dp:Array = [ { label:"New York", data: "New York" }, { label:"Miami Beach", data: "Miami Beach" } ]; ]]> </fx:Script> <mx:ComboBox id="cb" editable="false" width="100" dataProvider="{dp}" /> </s:Application>
2) Good Practice
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="1024" minHeight="768" creationComplete="creationCompleteHandler(event)"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; public var dp:Array = [ { label:"New York", data: "New York" }, { label:"Miami Beach", data: "Miami Beach" } ]; protected function creationCompleteHandler(event:FlexEvent):void { cb.dataProvider = dp; } ]]> </fx:Script> <mx:ComboBox id="cb" editable="false" width="100" /> </s:Application>
Comment:
1) If we just want to fetch data which is clearly known at compile time or can be filled with at run time, we can just assign the data to destination instead of binding data which cost overheads.
5. Binding Class and Binding Property at the Same Time
package vo { [Bindable] public class Student { [Bindable] public var id:int; public var name:String; public var gender:String; public function Student(id:int, name:String, gender:String) { this.id = id; this.name = name; this.gender = gender; } } }
Comment:
1) The class has already been assigned as [Bindable], so there is no need to assign a specific attribute as [Bindable] which will trigger a warning.