Article by Steven.
Published: February 25, 2010 at 18:13
Category: AIR, Flex, LiveCycle Data Services
Using conditional binding in Flex and AIR applications
< back to overviewEveryone knows by now that variable binding is something that is constantly used in Flex and AIR applications. The simplest way of using this feature is making use of the [Bindable]
metadata tag. However, there’s a second way that is commonly used and that is the <mx:Binding> tag. This one is used especially in combination with the first one to create a system of two-way binding in Flex applications.
But what about conditional binding? What about when you only want to use binding expressions in a certain view state, because, for example, a certain component only exists in e certain state? Assume the following piece of code, with "valueObject" being a complex object type:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Binding source="inputField.selectedItem.id" destination="valueObject.propertyId"/> <mx:states> <mx:State name="secondState"> <mx:RemoveChild target="{inputField}"/> </mx:State> </mx:states> <mx:ComboBox id="inputField" selectedItem="{valueObject.property}"/> </mx:Application>
Now, what we have here is a binding system that works perfectly as it should. Even when the application goes into the "secondState", everything still keeps working as you would expect. So, you might be wondering why-o-why would you need conditional binding? Well, let me explain that for you with an example situation I came across.
When you're working with LiveCycle Data Services, one of its key features is the <mx:DataService>. I'm not going to explain the DataService here, but I can say that this service allows you to connect in real-time to your back end using the RTMP channel (Real-Time Messaging Protocol). This very impressive feature lets you update items and display the updates instantaneously on all other connected applications. But it also has another feature, namely the fact that you can enable/disbable buttons or other functionality using the commitRequired property that is part of this DataService class. Now, it is this property that gets us into trouble when using binding on components that may not exist in other view states. The reason for that is the fact that this commitRequired property is monitoring every property of a [Managed] valueObject, so when that valueObject's property is changed, it will be set to true to indicate that there are some uncommitted changes.
However, when you remove the input field from the view state by means of an <mx:RemoveChild> tag, the binding system is also triggered and the value that is bound to that input field is altered. And that is actually triggering the commitRequired property in itself. That means that you're actually getting a functional mistake in your code. Now, there are probably several ways to solve this issue, but here's the one that suited my purpose the most in this particular project.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()"> <mx:Script> <![CDATA[ private function initApp():void { BindingUtils.bindSetter(setCustomProperty, inputField, "selectedItem"); } private function setCustomProperty(value:Object):void { if((value != null) && (currentState != "secondState")) { valueObject.propertyId = value.id; } } ]]> </mx:Script> <mx:states> <mx:State name="secondState"> <mx:RemoveChild target="{inputField}"/> </mx:State> </mx:states> <mx:ComboBox id="inputField" selectedItem="{valueObject.property}"/> </mx:Application>
In this way, you can check for the binding being valid or being necessary in the method that is triggered automatically when the accompanying value has been altered. That give you a great flexibility in what you can do when the selectedItem property of the combobox field is adjusted. It does not only allow you to block the binding all together, but it also allows you to maybe set another property in another value object, for example. I wouls say: just let your imagination run free...
< back to overview
Albert on February 25, 2010 at 11:01 pm
Hi,
very nice piece of code – helps me a lot!
It is good to know that there is something like BindUtils.
THX
Albert