This approach to component development and architectures will change your perspective on Flex software development! Consider the myriad situations when you want to add sophisticated functionality like zoom, drag-n-drop, swapping, MDI window minimizing, etc. Instead of designing subclasses or building complex compositions of nested components, developers can create distinct behavior components. These behavior components are then dynamically attached to target components and inject functionality.
I must admit that this software concept is not new. Consider the very popular JQuery UI Interactions. The JQuery UI Resizable code provides functionality to allow 1 or more HTML components to be dynamically resized. Other functionality exists for dragging, dropping, selecting, etc.
During Jan ‘09 – at FlexCamp OC in Irvine, CA – I presented a new topic called Flex Behavior Injection. Below is an improved version of the slide deck that I presented at that conference. These slides are interactive; simply click to go to the next or previous slide. You can also zoom the slides using the slide control bar…
Of course, what good is a slide deck without a live application and code samples? Below is a live version of a well-known Adobe application that demonstrates a charting dashboard solution with multi-chart interactions. Selecting a data point on a chart triggers filters and auto-updates dependent charts. With two (2) lines of code, I have enhanced that application to use injected behaviors for swapping and zooming. Click the picture below to play with the live Flex application.
Here are some helpful tips: To zoom, use the toolbar to select which chart you want to zoom, then click the Zoom button.
To swap a chart:
As you drag a chart around, watch how the other charts will swap positions dynamically, on-the-fly as you drag. Even better, with view states, your chart could be coded to change reconfig its states after resizing… so swapping could also change the layouts of each chart. For example, if placed in an narrow vertical area, the panel could change state to display a datagrid instead of a chart… you can imagine the sensation and rich user experience that you could offer to users.
Below is the main code for the sample application. Notice the Zoomer component tag that is highlighted on line 14. When activated (click event on line 26), the Zoomer handles all nesting and constraint issues for the target component when it zooms. And – best of all – the Zoomer handles details of un-zooming the component back to its original settings/location. You can easily imagine the enormous pain of trying to manually cache and restore settings and anchors…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" > <mx:Script> <![CDATA[ [Bindable] private var _target : UIComponent = null; ]]> </mx:Script> <!-- RPC Dataservice component for the chart XML data --> <mx:HTTPService id="srv" url="/data/dashboard4.xml" useProxy="false" result="resultHandler(event)"/> <!-- Behavior components --> <behaviour:Zoomer id="zoomer" target="{_target}" /> <swap:Swapper id="swapper" allowedDrops="{[allRegions,regionBreakdown,regionDetail]}" active="{_canSwap}" /> <mx:ApplicationControlBar left="10" right="10" top="5"> <mx:Label text="Chart to Zoom:"/> <mx:RadioButton label="All Regions" click="_target = allRegions;" /> <mx:RadioButton label="Breakdown" click="_target = regionBreakdown;" /> <mx:RadioButton label="Details" click="_target = regionDetail;" /> <mx:Button label="{zoomer.isZoomed ? 'UnZoom' : 'Zoom'}" click="zoomer.play();" /> <mx:Spacer width="100%" height="10" /> <mx:CheckBox label="Swap Enabled" selected="false" click="_canSwap = (event.target as CheckBox).selected;" /> </mx:ApplicationControlBar> <mx:Canvas id="content" top="50" bottom="10" label="10" right="10" left="10" horizontalScrollPolicy="off" verticalScrollPolicy="off"> <views:AllRegions id="allRegions" width="{content.width/2 - 10}" height="100%" left="0" revenueData="{slicedMonthData.source}" monthChange="monthChange()" /> <views:RegionBreakdown id="regionBreakdown" width="{content.width/2}" right="0" height="{content.height/2 - 10}" top="0" regionChange="regionChange()" /> <views:RegionDetail id="regionDetail" width="{content.width/2}" right="0" height="{content.height/2 - 10}" bottom="0" revenueData="{slicedRegionData.source}" /> </mx:Canvas> </mx:Application> |
This concept is very powerful. Your view components are not required to know about zooming or swapping (etc.) nor are you – the developer – required to configure special view hierarchies or plan for other considerations. Your coding style remains unchanged and your framework(s) [e.g. Cairngorm, CGX, Mate, etc.] remains unchanged.
Many people have asked for the source code to these components. This code will be open-sourced soon and the release is planned within the near future. Please consider rating this blog post and submitting some comments. You may subscribe to my blog RSS for auto-notifications when the Flex Behavior library is released. ![]()
Hi,
Saw this at Flex Camp Orange County, but have been away from Flex since. Have you released any code yet?
Cheers,
Colin
Very buggy.
Yes, the Swapper has some sensitivities to dragging and the Zoomer has some z-oder and alph issues with Panels.
While the code is reasonably stable, it has not been completely bug-proofed nor optimized for production release. The mx.effects.* Move and Resize classes should be replaced with the Tweener class. And more…
When this code is released as open-source, it is my hope that the community will contribute enhancements and new behavior components for us all to share.
Thomas,
Kudos on an awesome job. I cannot wait to get my hands on this. What a fantastic time saver and way to rapidly integrate new behaviors into an app! Let me know when it’s available.
Andrew
P.S. – Like the new blog!
Andrew Gscheidle’s last blog post..Problems "moving" items from one array collection to another
Hey Thomas,
I’ve been thinking along exactly the same lines lately! I wish I could have made it to CA for that presentation now. I’ve just released Bifff – A framework that focuses on the injection part of Behavior Injection. It will work perfectly together with what you are doing! It allows you to hook behaviors up to views with a full css syntax.
I haven’t really been working on the behavior part much at all, just on the injection, but there is/will be a tag you can use to connect behavior classes like the ones you are releasing to any matched view.
Visit the following for examples of what I’m talking about.