EladElrom.com

Deep Dive Into Technology

Tip: code editing in Flash Catalyst

Flash Catalyst public beta, doesn’t allow you to edit code while in ‘CODE’ view. I was running into issues trying to remove ‘tracking’ from text property that TLF doesn’t support.

Workaround: you can just right click the file you want to edit and select ‘Open With’ and then select ‘Text Editor’. Once you made your changed right click the document and select ‘Save’ from the right click context menu. Once you saved the file the changes will be committed.

13

Thanks @boobiestar for finding the workaround.

Flash Catalyst: not just a designer tool – developers workflow techniques

Flash Catalyst enables designers to increase their creative productivity and leverage their existing skills to create a stand-alone Flex application. It also facilitates collaborating in a team when creating Flex applications. Designers can create their graphics using Adobe Photoshop CS4, Illustrator CS4, or Adobe Fireworks CS4, and then convert these graphics into a Flex application by importing the native files into Catalyst, while keeping the layers intact. Catalyst acts as a bridge between Flex Builder and CS4.

This is all great, but as a developer you shouldn’t wait for designers to adopt to Catalyst and you can leverage Catalyst today.

In this post, I would like to talk about integration and workflow between Flash Catalyst and Flex working with Catalyst as a developer tool. This blog post is based on my experience working with Catalyst and is based on creating production grade applications. I believe that Flash Catalyst is a valuable tool and once you get to work with it and utilize it well, you will find it hard to work without it, mainly since it will save you valuable development time.

While Flash Catalyst got great reviews by many people since it was released as Beta, I also hear criticism in the Flex community about the tool and I would like to touch that before we diving into workflow tips.

This is the image from the T-Shirt given to participants during FlashCamp San Francisco this year:

catalyst

I am not sure if Flash Catalyst is really a gift to the designer?! Remember that old TV show Smurfs:

catalystgift1

I think that the source of the criticism is because of the following reasons:

  • Catalyst was labeled as a designer tool – Adobe put a label on Flash Catalyst and categorized the tool as a designer tool. Even the t-shirt in the above picture (from Adobe’s San Francisco Flash Camp event) labeled the product for designers, and not just designers, but female designers! We see the same on the Catalyst site (http://labs.adobe.com/technologies/flashcatalyst/) where you have a male developer on one side and female on the other side. I have to tell you, I have a lot of designer friends that are male and they are as talented and as capable as female designers. I personally believe that Adobe should release the product without putting any labels on who should use it.
  • High expectations – Adobe’s Marketing department has portrayed the product as if it allows seamless and effortless round tripping integration between CS4 and Flex, when in reality the round trip is not as seamless as described. Lower your expectations before using the tool.
  • Designer? tough pitch! – it’s a hard to tell designers “look, I will give you this amazing tool that will add work for you”. Designers are busy just as much as developers and many are not going to be as thrilled to adopt to a new tool that will require them to put more time and add them more responsibilities.
  • Adoption – designers adopting the technology may take a year or two since although it’s similar to other design products, there is still a learning curve and round tripping should be improved for better integration.


Who feels the pain? Designers or developers?

When it comes to skinning, interactivity and converting pixels to code, I believe that developers are feeling the pain much more than designers, since every time they need to skin a component or create interactivity, coding in Flex 3 is a tedious process and not easy unless you do it on a regular basis. Sure, designers feel the pain when their work is degraded during translation of graphics to code, but it’s usually solved by going over the work with the developer and adjusting the pixels.

4

Developers can benefits from using Catalyst:

  • Speed: increase your development time for simple to complex projects.
  • Agile workflow: work parallel with designers
  • Interaction design: add interactivity with the help of a designer.
  • Consistent graphics: There’s no need to slice graphics and skin components, since Catalyst takes care of that part, and the files created in CS4 convert easily.
  • Prototyping: create prototype applications.
  • Developers tool – you can leverage Catalyst as a developer without knowing how to use Illustrator or Photoshop.
  • How you can leverage Flash Catalyst as a developer:

    Create your view in Catalyst and integrate it using the presentation model

    Before using Catalyst you would get a comp from a designer and convert it into code. That process, at least to me, was a painful process that I always hated since I have to bother myself with tweaking CSS files and creating custom components which takes a lot of effort on complex components. With Catalyst you can import Illustrator / Photoshop files to Catalyst without opening CS products. I found that the best approach is to identify the different views you would like to break your application into components instead of trying to create one application. When you create an application you usually break your views to different components and I would do the same with Catalyst. What I mean is that you would figure out how you would like to split your view and create Catalyst projects based on that.

    Your assumption should be that you will have to change the Catalyst’s code and adjust it instead of assuming that the code Catalyst will spit out will be production grade code. Once you completed your work with Catalyst you can import, the FXP (Flash XML Project) file into Flash Builder and separate the ‘view’ from the ‘logic’ using the presentation model (similar to code behind) design pattern. There are many presentation model approaches, but the key is to have a ‘clean’ code that doesn’t have functionality so you can easily make changes to the view and follow Flex 4 and Catalyst architecture of separating pixels from the plumbing. You would import it as it’s own project and copy paste the classes you need while refactoring the location and names, as well as changing the generated code so it’s more readable.

    Skin component

    Another useful technique I found with Flash Catalyst is to skin components or at least create the scaffolding to skin components. For instance if you want to skin a button, sure you can code the class and states from scratch, but it will be done faster with Catalyst. Using Catalyst you can easily take an Illustrator file and convert a pixel to a button or any of the available components in Catalyst as well as create the states and interactivity which will save you time as well as generate FXG when available. FC also uses optimization techniques when possible, such as package pixels in a SWF.

    Using the FXG rather than images can give you a much better crisp look to your applications, not to mention decrease the size of your SWFs (if image embedded) or increase performance since the FP10 drawing API is faster than loading external images during run-time.

    21


    Create interactivity scaffolding

    I used Catalyst many times to create simple wire framing for interactivity. For instance, let’s say you have three components that you want to create animation (states) on certain user gesture, you can create boxed using Rectangle and convert them into ‘Custom / Generic Component’ then add the different states and interactivity. Export the project as FXP and then use the files as the scaffolding in Flash Builder and replace the custom component with the real component.

    12


    Designers and developers can work in parallel

    The designer can create the pixel and adjust the pixel as you need to make changes. So while you will be the one converting the pixel into code, you can work with the designer to make changes as you need them. For instance, you may notice that adding a shade to a vector graphic in Illustrator will convert the graphic into an image in Catalyst that doesn’t happens all the time but in certain cases, so you can work with the designer and have these images adjusted so they can turn into FXG code. As you work with the designer you can show him/her how you are working with Catalyst so the designer can slowly take over some of Catalyst work when he/she is ready.

    I am sure that as Catalyst rolls out of Beta the round tripping and integration with FB4 will be easier, meanwhile have fun and enjoy the tool when you can.

    Cheers, Elad Elrom :)

    Getting Strarted with Open Source Media Framework (OSMF) formerly Strobe

    The Open Source Media Framework (OSMF) formerly known as Strobe goes open source and provides a a framework for media playback of any kind.

    To download the code visit:
    http://opensource.adobe.com/wiki/display/osmf/Open+Source+Media+Framework

    The video player ecosystem is complex. There are other elements that make a video player a complete composition, such as advertisement elements, social network elements, reporting, content management, DRM etc. Adobe recently announced a new framework called Adobe Open Source Media Framework that is aimed at solving these issues.

    OSMF is an open source (vanity license) AS3 media framework that supports the workflow around video playback and monetization. Video players have different features set. The skins are different and the integration is different as well as the architecture workflow. But they do essentially the same thing and can be created using the OSMF framework. The framework is based on the quality of the video player (OVP) and addresses the common challenges.
    Adobe vanity license means that it’s ok to use and redistribute. Modifications can be submitted to Adobe for redistribution.

    The foundation of the framework is Qos (quality of service), which focuses on OVP and provides a quick start for playing videos (smallest buffer size needed to start the video), efficient connection logic, and switching bitrates dynamically (recall metric monitor service in OVP).

    The framework by itself is not powerful without having the CDNs and the publishers onboard. Adobe OSMF is based on the “chicken and the egg” theory, meaning which will come first? In fact, Adobe is currently trying to get the publishers and the CDNs onboard and it seem that they got very positive responses. The idea is that each CDN will integrate their plugins to the OSMF framework and the publisher will be able to easily switch CDNs. This type of pluggable component can allow publisher to easily switch as well as test performance and service over different CDNs.
    Advantages:

    • Reduce the barrier of entry for new publishers – by offering a framework to integrate the different pieces of the video player, new publishers can get started quickly and with fewer resources and scale up as requirements increase.
    • Provide flexible framework – OSMF provides an easy way to extend each component and allow these components to act as a Lego piece that can be compositable and extensible.
    • Leverage existing code – The OSMF framework uses the Flash Player from Open Video Player (OVP).
    • Drive Standard and allow custom workflows – many of the elements that connect to a video player are not standard yet and Adobe OSMF will help standardize these components as well as allow them to be configured.
    • No runtimes or framework dependency – the framework is based on Flash 10 AS3 and is not depend on any framework such as Flex SDK, Cairngorm or others. With that said some integrated elements may be created using a framework but these are loosely coupled and can be replaced if needed.
    • Partners focus – There are two partners: publishers and CDNs. Each can focused on their expertise. CDN can focus on services and integration and publisher can focus on user experience.
    • Integration with existing Adobe tools – Adobe OSMF will be integrated with other Adobe Suite tools and services such as Catalyst, Illustrator, FMS 3.5 and FMRMS.
    • Optimize – by the ability to separate the core framework and each element as a separate SWC you can increase performance by keeping file size to the minimum and based on components used.

    The Adobe OSMF framework consists of three interests, which can be represented as an MVC pattern, as follows:

    • Model (Media elements) – media element (based on IMediaElement) may be video, image, SWF or others. Every media element has defined capabilities (traits based on IMediaTrait) and a life cycle, they are called Regions, for instance Region 1 (Image), Region 2 (Video) etc. Each media element implement IMediaElement contract, which contains the dynamic media traits (capabilities) and you can add or modify a trait. The traits are the building blocks and they can be set once and be reused.
    • Controller (Media compositions) – a media composition (IMediaFactory) is a collection of media elements. Each media can be rendered based on set of rules as well as media region that define how to use the capability and the life cycle.
    • View (Media configurations) – collection of media regions with properties that map to defined capabilities. Each media region can render each media element and can be spatially arranged and the entire media configuration can be the stage.

    Let’s take a closer look at the higher architecture. The UI management is the set of tools we use to create our video player and skin it such as Flash Professional, Flex and soon we will be able to use Flash Catalyst for Flash 10 applications. Advertising companies such as DoubleClick or eyewonder allow us to add rich advertisement elements such as pre, mid and post roll ads, in playlist, or as companion ads or overlay ads. Applications provided by sites such as KickApps and gigya allowing embedding of the video player in social networks such as Facebook. The Flash Platform enable playback of video files. Companies such as Level(3) and Akamai provide syndications of feeds that can be consumed by other APIs. Lastly, stream management is available through Adobe’s server.

    strobe1

    The framework architecture was designed to allow you to integrate at multiple points and support different use cases, it also allow to use only the pieces you need, as well as the ability to scale up when ready. There are three types of implementation you may find useful.

    • Media Framework (level 1 integration) – small in size and include the basic integration such as the video player by OVP and pluggable CDNs. It allows hooking into your higher-level API, tweak the UI and access the needed classes and methods you define such as play and pause.
    • Media Framework and Composition Framework (level 2 integration) – In addition to level 1 level 2 allows creating a composition framework, which includes the ability to integrate to plugins that can provide monetization workflow for ads and tracking.
    • Configuration Framework, Media Framework and Composition Framework (level 3 integration) – in addition to the features that level 2 and level 1 offers, the level 3 integration offers dynamic chrome and syndication.

    strobe2

    Let’s see the framework in action

    Let’s take a look at a simple implementation of the framework provided by Adobe based on the beta version. Keep in mind that the implementation was provided by Adobe and it’s under Adobe agreement; please refer to Adobe in regarding to the license agreement in term of usage.

    package com.adobe.strobe.player
    {
    	import com.adobe.strobe.loaders.*;
    	import com.adobe.strobe.media.*;
    	import com.adobe.strobe.media.events.*;
    	import com.adobe.strobe.traits.*;
    	import com.adobe.strobe.traits.events.*;
    	import com.adobe.strobe.view.*;
    
    	import flash.events.*;
    	import flash.net.*;
    
    	public class MainWindow extends MainWindowLayout
    	{
    

    The childrenCreated method will be called automatically by the component once the child objects are created, since it’s replacing the default UIComponent method.
    We create the MediaFactory, which holds all the media element using IMediaInfo. We than can call the registerDefaultMedia. And adds event listeners to the buttons. As well as bring back mediaPlayer object which is the component which is capable of playing any type of media by holding a media element that has all the traits we needs such as IPausible, which is a trait to pause and resume playing.

    override protected function childrenCreated():void
    		{
    			super.childrenCreated();
    
    			// Construct a loader factory:
     			factory = new MediaFactory();
    			registerDefaultMedia(factory);
    
    			// Add button handlers:
    			buttonStop.addEventListener(MouseEvent.CLICK,onStopClick);
    			buttonPlay.addEventListener(MouseEvent.CLICK,onPlayClick);
    			buttonPause.addEventListener(MouseEvent.CLICK,onPauseClick);
    			buttonResume.addEventListener(MouseEvent.CLICK,onResumeClick);
    			buttonToggleMute.addEventListener(MouseEvent.CLICK,onToggleMuteClick);
    			buttonLoad.addEventListener(MouseEvent.CLICK,onLoadClick);
    
    			// Get a reference to our player:
    			player = flexMediaPlayer.mediaPlayer;
    			player.scaleMode = ScaleMode.LETTERBOX;
    		}
    

    registerDefaultMedia method creates all the media element that our application will be supporting, such as progressive download, streaming, audio files, images and SWFs.

    private function registerDefaultMedia(factory:IMediaFactory):void
    		{
     			var loader:ILoader = new VideoLoader();
    			factory.addMediaInfo
    				( new MediaInfo
    					( "progressive"
    					, loader as IMediaResourceHandler
    					, VideoElement
    					, [VideoLoader]
    					)
    				);
    
     			loader = new RTMPLoader();
    			factory.addMediaInfo
    				( new MediaInfo
    					( "streaming"
    					, loader as IMediaResourceHandler
    					, VideoElement
    					, [RTMPLoader]
    					)
    				);
    
    			loader = new SoundLoader();
    			factory.addMediaInfo
    				( new MediaInfo
    					( "audio"
    					, loader as IMediaResourceHandler
    					, SoundElement
    					, [SoundLoader]
    					)
    				);
    
    			loader = new ImageLoader();
    			factory.addMediaInfo
    				( new MediaInfo
    					( "image"
    					, loader as IMediaResourceHandler
    					, ImageElement
    					, [new ImageLoader()]
    					)
    				);
    
    			loader = new SWFLoader();
    			factory.addMediaInfo
    				( new MediaInfo
    					( "swf"
    					, loader as IMediaResourceHandler
    					, ImageElement
    					, [SWFLoader]
    					)
    				);
    		}
    

    loadMediaByURL method creates new media element based on the URL the user provided add listener and set it in our player component.

    		private function loadMediaByURL(url:IURLResource):void
    		{
    			// Stop listening to the current media, if any.
    			toggleMediaListeners(player.media,false);
    
    			// Create the new media.
    			var media:IMediaElement = factory.createMediaElement(url);
    
    			// Listen for events related to the new media.
    			toggleMediaListeners(media,true);
    
    			// Set it on our media player.
    			player.media = media;
    		}
    

    toggleMediaListeners method adds the event listeners to the media. Once the state have changed and the on flag is set to true it will call the event handler onMediaStateChange. The media element has a trait for loading the asset and once the onLoadableStateChange is captured the text field will display the information.

    		private function toggleMediaListeners(media:IMediaElement,on:Boolean):void
    		{
    			if (media != null)
    			{
    				if (on)
    				{
    					media.addEventListener(MediaStateChangeEvent.STATE_CHANGE,onMediaStateChange);
    				}
    				else
    				{
    					media.removeEventListener(MediaStateChangeEvent.STATE_CHANGE,onMediaStateChange);
    				}
    
    				var loadable:ILoadable = media.getTrait(ILoadable) as ILoadable;
    				if (loadable)
    				{
    					if (on)
    					{
    						loadable.addEventListener(LoadableEvent.LOADABLE_STATE_CHANGE,onLoadableStateChange);
    					}
    					else
    					{
    						loadable.removeEventListener(LoadableEvent.LOADABLE_STATE_CHANGE,onLoadableStateChange);
    					}
    				}
    			}
    		}
    

    The event listener will handle the interaction with the media element based on the traits that got assign to the media.

    		private function onStopClick(event:MouseEvent):void
    		{
    			player.stop();
    		}
    
    		private function onPlayClick(event:MouseEvent):void
    		{
    			player.play();
    		}
    
    		private function onLoadClick(event:MouseEvent):void
    		{
    			var url:String = urlInput.text;
    			if (url.length > 0)
    			{
    				player.unload();
    				loadMediaByURL(new URLResource(url));
    			}
    		}
    
    		private function onLoadableStateChange(event:LoadableEvent):void
    		{
    			loadState.text = event.newState.toString();
    		}
    

    The onMediaStateChange event handler will handle the display and hiding of the toolbar.

    		private function onMediaStateChange(event:MediaStateChangeEvent):void
    		{
    			if (player.media)
    			{
    				buttonStop.visible 	= buttonPlay.visible 	= player.media.getTrait(IPlayable) != null;
    				buttonPause.visible = buttonResume.visible  = player.media.getTrait(IPlayable) != null;
    				buttonToggleMute.visible = player.media.getTrait(IAudible) != null;
    			}
    		}
    
    		private var factory:IMediaFactory;
    		private var media:IMediaElement;
    		private var player:MediaPlayer;
    

    Constants to hold the different media files we can test.

    		private static const REMOTE_PROGRESSIVE:String 	= "http://flipside.corp.adobe.com/pirates3/Pirates3-1.flv";
    		private static const REMOTE_MP3:String 			= "http://flipside.corp.adobe.com/brian/strobe/media/Remember.mp3";
    		private static const REMOTE_STREAM:String 		= "rtmp://flipside.corp.adobe.com/trailers/EvanAlmighty";
    		private static const REMOTE_IMAGE:String 		= "http://www.adobe.com/products/mediaplayer/assets/images/amp_icon.jpg";
    		private static const REMOTE_SWF:String 			= "http://flipside.corp.adobe.com/testing/swfPlayback/as3/Objects/Color/ObjClr_setRGB.swf"
    	}
    }
    

    strobe3

    Under the hood Flex data model using the fx:Model and fx:XML tags

    When creating data model there are two popular ways to create data model in addition to VO / DTO. You can use the fx:Model and the fx:XML tags. These tags are mxmlc compiler tag. What it means is that the compiler handles these tags differently than the regular tags in MXML. In case you are like me and like to dig deep into how the mxmlc works than keep reading… In the Model or XML tags the source property can be set to an external source, however the compiler retrieve the information and set it as an ObjectProxy, which allow the object to be bindable, additionally it does direct assignment so there is no service call to retrieve the data as you may expect from an MXML tag. Consider the code below:

    <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/halo"
    			   minWidth="1024" minHeight="768"
                               creationComplete="creationCompleteHandler(event)">
    	<fx:Script>
    		<![CDATA[
    			import mx.events.FlexEvent;
    
    			protected function creationCompleteHandler(event:FlexEvent):void
    			{
    				trace("infoVO full name property: "+this.infoVO.fullName);
    				trace("info2VO full name property: "+this.info2VO.fullName);
    			}
    
    		]]>
    	</fx:Script>
    
    	<fx:Declarations>
    
    		<fx:Model id="infoVO">
    			<root>
    				<fullName>John Doe</fullName>
    				<email>john@gmail.com</email>
    				<phone>212-222-2222</phone>
    				<zip>10001</zip>
    			</root>
    		</fx:Model>
    
    		<fx:Model id="info2VO" source="Info.xml" />
    
    	</fx:Declarations>
    
    </s:Application>
    

    We have two Model tags in the code and although one tag calls an xml using the source property and another one does direct assignment the mxmlc compile will generate the same code for both of these tags.

    Take a look at what the compiler does when you use set infoVO and info2VO with the source property:

    private function _DataModel_ObjectProxy2_i() : mx.utils.ObjectProxy
    {
    	var temp : mx.utils.ObjectProxy = new mx.utils.ObjectProxy();
    	temp.fullName = "John Doe";
    	temp.email = "john@gmail.com";
    	temp.phone = "212-222-2222";
    	temp.zip = 10001;
    	info2VO = temp;
    	return temp;
    }
    
    private function _DataModel_ObjectProxy1_i() : mx.utils.ObjectProxy
    {
    	var temp : mx.utils.ObjectProxy = new mx.utils.ObjectProxy();
    	temp.fullName = "John Doe";
    	temp.email = "john@gmail.com";
    	temp.phone = "212-222-2222";
    	temp.zip = 10001;
    	infoVO = temp;
    	return temp;
    }
    

    And here’s what the mxmlc code generated to create the binding tag:

        [Bindable(event="propertyChange")]
        public function get info2VO():mx.utils.ObjectProxy
        {
            return this._1945369341info2VO;
        }
    
        public function set info2VO(value:mx.utils.ObjectProxy):void
        {
        	var oldValue:Object = this._1945369341info2VO;
            if (oldValue !== value)
            {
                this._1945369341info2VO = value;
                this.dispatchEvent(mx.events.PropertyChangeEvent.createUpdateEvent(this, "info2VO", oldValue, value));
            }
        }
    
    	/**
    	 * generated bindable wrapper for property infoVO (public)
    	 * - generated setter
    	 * - generated getter
    	 * - original public var 'infoVO' moved to '_1184171033infoVO'
    	 */
    
        [Bindable(event="propertyChange")]
        public function get infoVO():mx.utils.ObjectProxy
        {
            return this._1184171033infoVO;
        }
    
        public function set infoVO(value:mx.utils.ObjectProxy):void
        {
        	var oldValue:Object = this._1184171033infoVO;
            if (oldValue !== value)
            {
                this._1184171033infoVO = value;
                this.dispatchEvent(mx.events.PropertyChangeEvent.createUpdateEvent(this, "infoVO", oldValue, value));
            }
        }
    

    Since the mxmlc compiler create an ObjectProxy component it allows us to bind these properties as in the example below:

    <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/halo"
    			   minWidth="1024" minHeight="768">
    
    	<s:layout>
    		<s:BasicLayout/>
    	</s:layout>
    
    	<fx:Declarations>
    		<fx:Model id="infoVO">
    			<root>
    				<fullName>{fullNameTextInput.text}</fullName>
    				<email>{emailTextInput.text}</email>
    				<phone>{phoneTextInput.text}</phone>
    				<zip>{zipTextInput.text}</zip>
    			</root>
    		</fx:Model>
    	</fx:Declarations>
    
    	<mx:DataGrid x="11" y="164" id="dataGrid"
    				 dataProvider="{infoVO}">
    		<mx:columns>
    			<mx:DataGridColumn
    				headerText="fullName"
    				dataField="fullName"/>
    			<mx:DataGridColumn
    				headerText="email"
    				dataField="email"/>
    			<mx:DataGridColumn
    				headerText="phone"
    				dataField="phone"/>
    			<mx:DataGridColumn
    				headerText="zip"
    				dataField="zip"/>
    		</mx:columns>
    	</mx:DataGrid>
    
    	<mx:Form>
    		<mx:FormItem label="FullName">
    			<s:TextInput
    				id="fullNameTextInput"/>
    		</mx:FormItem>
    		<mx:FormItem label="Email">
    			<s:TextInput
    				id="emailTextInput"/>
    		</mx:FormItem>
    		<mx:FormItem label="Phone">
    			<s:TextInput
    				id="phoneTextInput"/>
    		</mx:FormItem>
    		<mx:FormItem label="Zip">
    			<s:TextInput
    				id="zipTextInput"/>
    		</mx:FormItem>
    	</mx:Form>
    </s:Application>
    

    Here’s a screen shot of the application:
    Flex Data Model

    It valuable to understand how the mxmlc works and use these tags when needed.

    Speaking at InsideRIA first conference about Test Driven Development (TDD)

    InsideRIA first conference is just around the corner (August 23-24, 2009 in San Jose, CA at the eBay facilities). This 2-day event will dig into the nitty gritty of developing for the RIA space with technology agnostic approach. Sunday will be hands-on workshops to get you familiar with a few of the RIA platforms and Monday will be a full day of sessions.

    insideria_conference_promo

    My session will be on Monday between 1PM – 2PM. Although I’m late about publishing information about my session it’s better late than never.

    Building Applications using Test Driven Development (TDD)

    Unit testing and Test Driven Development (TDD) is one of the hottest architectural subjects in the latest years. Explore how to make development and scalability easier and less prone to errors. You will go through the development cycle of developing using TDD and get a complete overview on how to change your development cycle and move to TDD. You will see how to create Test Suites and Test Cases and tie them with your development cycle, integrate with framework as well as test visual component.

    Tickets are going fast, get your ticket to join this amazing event. Read more about the event here.

    Hope to see you there!

    Flex data binding five common misuse mistakes

    Data binding is one of the most used processes when building Flex applications, but at the same time, it’s a costly process and can delay initialization of an application (see my previous blog post). It’s a good idea to pay attention and ensure it’s used correctly and when needed. I compiled a list of five common pitfalls and incorrect misuses that developers do when building a Flex application and using the binding process.

    1. Using bindable when binding is not necessary

    Using unnecessary binding tags is when you bind a property that can be done easily without the binding tag. In cases where you don’t need to bind and you can do it with direct assignment then it’s best to avoid binding. I have seen this type of mistake many times in many shapes and forms. Take a look at the code below to illustrate one example:

    <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/halo"
         minWidth="1024" minHeight="768">
    
         <fx:Script>
              <![CDATA[
    
                   private var text:String = "hello world";
    
              ]]>
         </fx:Script>
    
         <s:layout>
              <s:VerticalLayout />
         </s:layout>
    
    	<s:TextInput id="textInput2" text="{text}"  />
    
    </s:Application>
    

    We have a text input with a text property binding to the text variable. Looks harmless enough, right? I have seen this type of tags often in Flex applications and I must admit that I have placed a few of these in the past myself. The mxmlc generates code to allow the binding. You will find that although you don’t need to bind the text String, since this is a one time assignment, the mxmlc still generates code to accommodate binding of the property. See part of the code generated by the mxmlc below:

    [Bindable(event="propertyChange")]
        public function get textInput2():spark.components.TextInput
        {
            return this._1559985461textInput2;
        }
    
        public function set textInput2(value:spark.components.TextInput):void
        {
        	var oldValue:Object = this._1559985461textInput2;
            if (oldValue !== value)
            {
                this._1559985461textInput2 = value;
                this.dispatchEvent(mx.events.PropertyChangeEvent.createUpdateEvent(this, "textInput2", oldValue, value));
            }
        }
    

    In this case we can do direct assignment of the value without the binding brackets:

    <s:TextInput id="textInput2" text="hello world"/>
    

    Or you can use an event (which is a much less costly than the binding process) to update the text property in case you need a variable to hold the value:

    <s:TextInput id="textInput2" creationComplete="textInput2.text=text"/>
    

    2. Using const as bindable event name

    When you use the bindable tag with custom name, the example below looks like a good idea:

    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));
    }
    

    We are assigning a static property to the event name and then we can use the same assignment to dispatch the event, however, when the value changes the binding tag doesn’t recognize the change. The reason is that the event name will be EVENT_CHANGED_CONST and not the value of the variable.

    3. Assuming execution order of binding

    A common mistake when binding is assuming that a binding order is in synchronous execution order. Events in ActionScript are executing in an asynchronous manner. Take a look at the example below:

    <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/halo"
         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:SimpleText id="simpleText" text="{buttonText}" />
         <s:Button label="{simpleText.text}" />
    
    </s:Application>
    

    The code may work, however, you are assuming that the simpleText text property was already set since the value of text is binding and not the actual text property. We also get a compile time warning. See figure below:

    binding pitfall

    Here’s another example, where we assume that the value of the first TextInput was already set. Also this type of assignment generates all the code to create binding from the mxmlc compiler. You have to consider if it’s worth it or if direct assignment (y=”35″) is a better choice.

    <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/halo"
         minWidth="1024" minHeight="768">
    
         <s:TextInput id="textInput1" x="10" y="0" />
         <s:TextInput id="textInput2" x="0" y="{textInput1.x+25}" />
    
    </s:Application>
    

    4. Assigning Binding tag when you can avoid it

    There are many cases where you can write your code easily without data binding and use ChangeWatcher or use events to assign a value. It’s recommended to avoid binding when it’s not needed. Consider the following code:

    <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/halo"
         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>
    

    Looks pretty standard code in Flex application, however, this type of binding is not needed since instead of binding you can do direct assigement using an event handler:

    <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/halo"
         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>
    

    5. Using binding class and binding property at the same time

    Another common mistake to set a class to be bindable and then assign each property in a class to be bindable as well. See the code below:

    package
    {
         [Bindable]
         public class CustomerVO
         {
              [Bindable]
              public var customerID:int;
    
              public function CustomerVO(customerID:int) {
                   this.customerID = customerID;
              }
         }
    }
    

    The reason that the bindable tag is not needed for the CustomerID property is because the class is already set to be bindable and every property in the class will be set to be bindable.

    Data binding contains tremendous value, but also holds disadvantages. I recommend ensuring it is being used correctly and when needed since data binding can create overhead and memory leaks, which will cause your application to suffer in terms of performance.

    [TurboBinding] metadata provides performance gain and additional functionality over the [Binding] tag

    I have created binding metadata called [TurboBinding], which provides performance advantage in addition to new features in comparison with the Binding metadata. To use the metadata, see the implementation example below (right click and select view source).

    implementation example
    The code is maintained under eladlib code base.

    Example of a simple tag:

    [TurboBinding(destination="simpleText.text")]
    

    Background

    Data binding is one of the most used processes when building Flex applications. it allows rapid development of Flex applications. Data binding allows you to pass data between different layers of the application automatically and makes development of Flex applications easy, fast and enjoyable. As Data binding contain tremendous value, there is also disadvantages: without understanding exactly how data binding works and ensuring it is being used correctly, and when needed, data binding can create overhead and memory leaks, which will cause your application to suffer in terms of performance.

    There are five techniques for using Data Binding:

    • Using curly brackets in MXML tags
    • Using the fx:Binding tag
    • Using the BindingUtils class
    • Implicit and explicit data binding

    I am not going to expand too much about the techniques available to bind properties but you can pre-order a new book I am co-authoring that will have a whole chapter devoted to data binding and all the techniques in Flex 4: Amazon link.

    The overhead can cause an application with thousands of Binding tags to choke for even half a second, which I will expand in more detail below. The alternative up until today was to use some of the other methods such as ChangeWatchers and BindingUtils class, however, they require management to avoid memory leaks and are not as easy as using the [Binding] metadata tag. Large Flex applications needs all the help they can get to get better performance and in my opinion, a half a second delay during initialization is not acceptable.

    TurboBinding metadata

    I completed an open source binding utility called [TurboBinding].

    TurboBinding is a lightweight binding class with a speed close to the BindingUtils class but with the ease of setting your binding as a metadata tag, just as you do with the Binding metadata. Here’s an example of using the TurboBinding metadata tag:

    [TurboBinding(destination="simpleText.text")]
    

    Remove binding

    In addition to performance gain [TurboBinding] provides additional functionality. For instance, let’s say you want to avoid memory leaks. since you don’t need to bind a property anymore, you can set the unwatchCounter property and it will remove the listener and avoid memory leaks. For instance, let’s say you are making a service call to retrieve customer information and once you receive the information you don’t need to bind anymore, you can set the unwatchCounter property to 1 and after the information is retrieved, it will clean up.

    [TurboBinding(source="textInputOne.text", destination="textInputTwo.text", unwatchCounter=5)]
    

    Two-way data binding

    Data binding process allows tying one object data with another object. The concept of data binding is connecting a source object with a destination object and once the source object changes, the destination object changes automatically. Additionally Flex 4 offers a two-way data binding, which is also known as bidirectional which allows two objects to be tied to each other allowing data to be changed when either object changes.
    In [TurboBinding] metadata I added the ability to bind two properties together. Add twoWay=”true” to add the two-way data binding. Note that once you use the twoWay property with unwatchCounter the binding will be removed from both binding instances.

     [TurboBinding(source="textInputOne.text", destination="textInputTwo.text", twoWay="true", unwatchCounter=5)]
    public function callBackFunction(newValue:String):void
    {
    trace(newValue);
    }
    

    Call back method

    As you saw in the example before, I set a method next to the [TurboBinding] metadata. what it will do is call back the method once the change is recognized, which is a great feature for times when you want to do an additional task after binding.

    Implementation example

    To use the utility you need to call the setup method, since the code is not generated using the mxmlc as in the [Binding] tag. The examples below includes example of using the unwatchCounter property, which removes the binding after 5 times the data changes, simple data binding and two way binding for two text input.

    implementation example

    xmlns:s=”library://ns.adobe.com/flex/spark”
    xmlns:mx=”libr