Friday, February 17, 2012

Deadly Flex interview Questions

This post is about the tough interview questions in Flex. There will always be some questions not answered by us. I have collected some of the tough interview questions and will update them periodically.

Question: If I have two functions with name function1 and function2 how can I call them at runtime using their name only, somewhat similar to reflection in Java. 
OR
How can I access a variable using its name as String parameter at run time in AS?
Answer: For accessing any function/property using its string name at run time we need to use this as shown below:




private function function1():void{

  Alert.show("One");

}

           

private function function2():void{

  Alert.show("Two");

}



protected function button1_clickHandler(event:MouseEvent):*

{

    for(var i:int = 1; i<=2; i++)

    {

        if(this["function" + i] is Function){

            this["function"+ i]();                       

            }

    }

}


And then we can call is using a simple click handler like:

<s:Button label="demo" click="button1_clickHandler(event)"/>

Question: I am using a ViewStack (or Accordion or any other navigator) and I have multiple VBox /NavigatorContent (etc.). When I move to other child of viestack I observed the scrollbars and I found it sets its content area size based on the first child. What can I do to fix this problem?
Answer: Set resizeToContent property to true. After that the content area will be re-sized automatically whenever we switch among children.

Question: I am having a scenario where I want user information to be available across the application. Shall I use FlexGlobals.topLevelApplication or static variables? Which one would be better?
Answer:  If we use FlexGlobals.topLevelApplication then our code gets bound to almost 90% of Flex classes and it becomes highly coupled, which is not good. The better way is to use static variable to convey that information. But the best way would be to inject value in our client instance using delegation or dependency injection library/framework e.g. Parsley.
You can find the interview questions about parsley here.

Question: What is a dynamic class? How is it different from Sealed class?
Answer:dynamic class defines an object that can be altered at run time by adding or changing properties and methods. A class that is not dynamic, such as the String class, is a sealed class. You cannot add properties or methods to a sealed class at run time. We create a dynamic class by using the dynamic attribute when you declare a class.
dynamic class Protean

{
    private var privateGreeting:String = "hi";
    public var publicGreeting:String = "hello";
    function Protean()
    {
        trace("Protean instance created");
    }
}


We can instantiate it and then can add properties or methods to it outside of class declarations.
var myProtean:Protean = new Protean();

myProtean.aString = "testing";
myProtean.aNumber = 3;
trace(myProtean.aString, myProtean.aNumber); // testing 3
myProtean.traceProtean = function ()
{
    trace(this.aString, this.aNumber);
};
myProtean.traceProtean(); // testing 3
more can be read here.



Question: What are the restrictions with a dynamic class? 
Answer: We can dynamically add only public properties and methods. Sealed classes are more efficient as they do not need to create a hash table to store the properties and methods that are unknown during compilation. 

Another obvious restriction is that dynamically added functions can’t access private members of the dynamic class. So if we don't need to add any new property/method later, it is best to use sealed classes.

Question: How can we instantiate a class at run-time in action-script?
Answer:In Java, we can do this using:

String className = "com.mittal.Navigator";
Class clazz = Class.forName(className);


If we want the same thing in Action Script we can use getDefinitionByName() method:

var testNav:AClass;
var clazz:Class = Class(getDefinitionByName("
com.mittal.Navigator"));
testNav = new clazz();

More can be read here.

Question: Is Object class dynamic?  OR
How are we able to add properties to a object at runtime? 
Answer:Objects can be created dynamically as:
var p = {} or
var p = new Object()
var dyna:Object = { firstName: "John", lastName: "Smith" };

As Object is a dynamic class, we can add new properties at runtime. If we need 100 objects then we can create an empty array and then keep on adding them.
var myArray:Array = [];
var object1:Object = {};
var object2:Object = {};

Question: I am having a formula and i want that to be executed. But I observed that there is no eval() in AS3, what can we do?
Answer: The better way is to use ExternalInterface API and execute the formula in java-script, otherwise the UI will be sluggish if it take a lot of time to execute. If we still want to find a work-around for eval we can check here.

Question: How can we clone (duplicate) an object in ActionScript 3?
Answer: Please check this post:

Question: When I run the following code I get error. How can we fix it?


interface If { ... }

class Impl implements If { ... }



function test(type:Class, obj) {

  return obj instanceof type;

}



test(If, new Impl());

The call to test on the last line returns false, but it should be true. How can I do this check right, with the requirement that it must be inside the function?
[Adapted from http://stackoverflow.com/questions/2401345/actionscript-instanceof-for-dynamic-interface]
Answer:First of all avoid using instanceof operator. And if we still want to use we should replace the test with:
if(Object is IInterface) 


Question: Can we define a constructor for an MXML component?
Answer: No we cannot define constructor for an MXML component but we can write event listener for preinitializeinitialize, or creationComplete event to replace the constructor.These events are all defined by the UIComponent class, and inherited by all of its subclasses. If we create an MXML component that is not a subclass of UIComponent, we cannot take advantage of these events. We can instead implement the IMXMLObject interface in ourMXML component, and then implement the IMXMLObject.initialized() method


Question: What is Shared Object? How is it different from Cookie?
Answer: Shared Objects are like browser Cookies. They are used to store data on hard disk of
user and call that data during the same session or in a later session.
1. Shared Objects don’t expire by default.Cookie can expire and they generally do at end of session.
2. Shared Objects mostly  have size of 100KB each.Cookies can be disabled by the user and generally size of a cookie is 4KB. Also there is a limit of 300 cookies total and 20 cookies at maximum per site.
3. SOs are no security threat. Applications can access only their own shared objects.Cookies are sometimes considered security threat.
4. SOs are stored in a location specified by application and they are not transmitted to server. They are store in a location specified by the browser and transmitted to server thorough http.
5. SOs can store simple data types (String, Array and Date).

Question: What are the various functions in class SharedObject?
Answer: They can be created and deleted using some standard functions:
clear()- Purges all of the data from the SharedObject object, and deletes the SharedObject file from the disk.
flush()- Immediately writes the SharedObject file to a file on the client.
getLocal()- Returns a reference to the client's domain-specific, local SharedObject object. If none exists, this method creates a new shared object on the client.
getSize()- Gets the size of the SharedObject file, in bytes. The default size limit is 100 KB, although it can be larger if the client allows it.
Along with them, the class SharedObject also have following properties –
data Read-only property that represents the collection of attributes the shared object stores.
onStatus The shared object's event handler that is invoked for every warning, error, or informational note.

Question: An example of using Shared Object?
Answer: The following example shows how to create one.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"

initialize="initApp()">

<mx:Script><![CDATA[

public var mySO:SharedObject;

[Bindable]

public var welcomeMessage:String;

public function initApp():void {

mySO = SharedObject.getLocal("mydata");

if (mySO.data.visitDate==null) {

welcomeMessage = "Hello first-timer!"

} else {

welcomeMessage = "Welcome back. You last visited on " +

getVisitDate();

}

}

private function getVisitDate():Date {

return mySO.data.visitDate;

}

private function storeDate():void {

mySO.data.visitDate = new Date();

mySO.flush();

}

private function deleteLSO():void {

// Deletes the SharedObject from the client machine.

// Next time they log in, they will be a 'first-timer'.

mySO.clear(); //Destroy the shared object

}

]]></mx:Script>

<mx:Label id="label1" text="{welcomeMessage}"/>

<mx:Button label="Log Out" click="storeDate()"/>

<mx:Button label="Delete LSO" click="deleteLSO()"/>

</mx:Application>


Question: What is local connection? How is this different from shared objects?
Answer: We can use LocalConnection to develop SWFs which can communicate to each other. LocalConnection object is used to call a method in another LocalConnection Object.The communication can be – within a single SWF file, between multiple SWF files, between content (SWF-based or HTML-based) in AIR applications, between content (SWF-based or HTML-based) in an AIR application and SWF content running in a browser. Unlike shared objects, they provide real-time exchange. We can use LocalConnection objects to communicate with in a single file, but that’s not a typical implementation. We can also use cross-scripting (it is when a SWF file communicates directly with another SWF file). This communication is done without use of fscommand() or JavaScript. These objects can communicate only among the files that are running on same client computer but they can be in different applications for example a file running in a browser and a SWF running in Adobe AIR. There will be two SFWs: one will be sending SWF and other will be receiving SWF. The sending side will have the method to be invoked, a LocalConnection object and a call to send() method The receiving side will also contain a LocalConnection object and a call to connect() method.This side will invoke the method from sending side. If we want two-way communication we need to use two connections. More.

Question: Can we exchange data between two local connections one in SWF running in our computer and other SWF accessed from some other computer on network? What are security restrictions while using local connection?
Answer: LocalConnection objects can communicate only among the files that are running on same client computer. We may call SWF from a network computer, but that will ultimately be running in our computer :)
The use of send() and connect() methods between the two sides for data exchange depend upon – files are in same domain, in different domains with predictable domain names, or in different domains with unpredictable or dynamic domain names. These are explained below.
Same Domain: The simplest one and permitted by default. Don’t need any security measure.

// receivingLC is in http://www.domain.com/receiving.swf

receivingLC.connect('myConnection');
// sendingLC is in http://www.domain.com/sending.swf
// myMethod() is defined in sending.swf
sendingLC.send('myConnection', 'myMethod');

Different domains with predictable domain names: When two SWF files from two different
domains communicate we need to allow communication between the two domains by calling the
allowDomain() method. We need to qualify the connection name in send() method with the
receiving side LocalConnection object’s domain’s name.


// receivingLC is in http://www.domain.com/receiving.swf

receivingLC.allowDomain('www.anotherdomain.com');

receivingLC.connect('myConnection');

// sendingLC is in http://www.anotherdomain.com/sending.swf

sendingLC.send('www.domain.com:myConnection', 'myMethod');

Different domains with unpredictable domain names: We may want receiving side more
portable between domains. So to avoid specifying the domain name in send() method, but to
show that both the sides are in different domain, we need to precede the connection name
with underscore (_) character in both send() and connect() calls. To allow communication
between two domains, we need to call allowDomain() and pass the allowed domain names to
allow calls. Alternatively, we can use wildcard (*) to allow all domains.


// receivingLC is in http://www.domain.com/receiving.swf

receivingLC.allowDomain('*');

receivingLC.connect('_myConnection');

// sendingLC is in http://www.anotherdomain.com/sending.swf

sendingLC.send('_myConnection', 'myMethod');
You can check more about this here.


Question: Differentiate allowDomain() and allowInsecureDomain() methods?
Answer: By default, a LocalConnection object is associated with the sandbox of the file that created it, and cross-domain calls to LocalConnection objects are not allowed unless you call the LocalConnection.allowDomain() method in the receiving file (the one which will receive the request from sender).
Both the methods are used for almost same purpose but the difference is -
allowInsecureDomain() method additionally permits SWF files from non-HTTPS origins to send LocalConnection calls to files from HTTPS origins. Consider a file X which is hosted using a secure protocol (https) and there is a file Y hosted on non-secure protocol. Then if Y wants to access method on X, X need to allow using allowInsecureDomain() method. We must call the allowInsecureDomain() method even if we are crossing a non-HTTPS/HTTPS boundary within the same domain; by default, LocalConnection calls are never permitted from non-HTTPS files to HTTPS files, even within the same domain.
When we load a file over HTTPS, we can be reasonably sure that the file will not be tampered with during delivery over the network. But if we permit a non-HTTPS file to make calls to the HTTPS file, we cannot trust the authenticity of LocalConnection calls arriving at our HTTPS file. That’s why using allowInsecureDomain () is not recommended.

Question: What is deep linking?
Answer: In a Flex application, we can smoothly move from one state to other, without fetching a
new page from server or refreshing the browser. But in page-oriented model of browser, every
state is coupled to URL and thus can be used to bookmark the URL, email to URL and to use
back-forward buttons. To add such URL-mapping to Flex application we use deep linking. This
works with certain browsers and also need scripting in browser to be enabled. This doesn’t work
with standalone Flash Player or AIR. When using this HistoryManager doesn’t work as it sets
the property historyManagementEnabled to false.

Question: What are the different ways of exchanging data with flex applications?
Answer: Flex applications generally lie in larger web applications that control security to state management. A flex application is generally loaded in a browser with in html wrapper which can also include JavaScript or other client side logic. There are many ways to interact – any combination of flashVars properties, query string parameters, the navigateToURL() method and ExternalInterface API.
To pass data to flex application, we can set flash variables in wrapper and then access them in
flex application using Application.application.parameters or
LoaderConfig.parameters objects.
We can use method of ExternalInterface API to call methods of Flex applications and vice
versa. We use addCallBack() method to expose methods of flex application to wrapper, and
use call() method to call methods in flex from wrapper. If wrapper is html we use them to
exchange data in JavaScript and Flex.
Flex -> Wrapper = call()
Wrapper -> Flex = addCallBack()
In some situations we want to open new window or navigate to a new location, then we use
navigateToURL() method. Although this is not part of ExternalInterface API, but this method let us
write JavaScript inside it, and invoke those functions inside resulting HTML page.

Question: What are the performance implications if we use ItemRenderer Function?
Answer: If we define an itemRendererFunction to determine the item renderer for each data item, Flex will not reuse item renderers. The itemRendererFunction must examine each data item and create the item renderers as necessary for the specific data item type. While Flex does not reuse item renderers, it only creates enough item renderers for the currently visible data items. For more information
http://help.adobe.com/en_US/flex/using/WS64909091-7042-4fb8-A243-8FD4E2990264.html

Question: What are the various ways to optimize item renderers?
Answer: Check this post.


Question: How can we change the default browser (say to Chrome) in FB?
Answer: We need to know the installation directory for chrome first. It is 
C:Documents and SettingsUserNameLocal SettingsApplication DataGoogleChrome
for windows XP and differs for different OS.

Then in FB go to windows -> preferennces -> General -> Web Browser and click on "Use extenral web browser" and click New. Then give the details of browser name and location of Chrome.exe file. And then select it and its all done!!


Updated on 27th Feb 2013

Question: What is the difference between deep copy and shallow copy?
Question: How can we use copy() method in ObjectUtil for deep copy? 
Question: Wen we use this method the type of the value object is lost if the value object does not have remote tag. How can we retain the type in such scenario?
Check the following link for all the answers:

Thursday, February 16, 2012

Custom WorkFlow Navigator Component

Recently I tried to create one simple and easy-to-use workflow navigator component. Suppose we want to fill one form which has five steps then this component can be used as workflow at top to show these steps. The end user would be able to click on any of the steps can move back and forth. This navigator takes String and Workflow items. If we give strings it will convert them to work-flow items before insertion. This code can still be refined and will be done periodically basis.



The main component class is WorkFlowNavigator which handles the complete logical aspects. This component extends SkinnableComponent and starts from the scratch. The class WorkFlowItem is responsible for displaying the items in the navigator. The navigator also includes next/previous arrow buttons which can be used to navigate. This component also provides option of clicking any of the workflow item (in case user wants to move back to that step), in that case navigator will be updated and all work-flow items following the selected item will be removed. Moreover an event will be dispatched to notify the user.



package mittal.components

{

    import flash.events.Event;

    import flash.events.MouseEvent;

   

    import mittal.events.WorkFlowEvent;

    import mittal.skins.WorkFlowNavigatorSkin;

    import mittal.valueObjects.WorkFlowItem;

   

    import mx.collections.ArrayCollection;

    import mx.collections.IList;

    import mx.controls.Alert;

    import mx.core.IFactory;

   

    import spark.components.Button;

    import spark.components.HGroup;

    import spark.components.supportClasses.SkinnableComponent;

   

    //--------------------------------------

    //  Events

    //--------------------------------------

    /**

     *  Dispatched when the data provider changes.

     *

     *  @eventType mittal.events.WorkFlowEvent.WORKFLOW_DATA_CHANGED

     * 

     *  @langversion 3.0

     *  @playerversion Flash 10

     *  @playerversion AIR 1.5

     *  @productversion Flex 4

     */

    [Event(name="workFlowDataProviderChanged", type="mittal.events.WorkFlowEvent")]

    /**

     *  Dispatched when the selected index changes.

     *

     *  @eventType mittal.events.WorkFlowEvent.SELECTED_INDEX_CHANGED

     * 

     *  @langversion 3.0

     *  @playerversion Flash 10

     *  @playerversion AIR 1.5

     *  @productversion Flex 4

     */

    [Event(name="selectedIndexChanged", type="mittal.events.WorkFlowEvent")]

    /**

     *  Dispatched when the next button is clicked.

     *

     *  @eventType mittal.events.WorkFlowEvent.WORKFLOW_NEXT_CLICK

     * 

     *  @langversion 3.0

     *  @playerversion Flash 10

     *  @playerversion AIR 1.5

     *  @productversion Flex 4

     */

    [Event(name="nextClicked", type="mittal.events.WorkFlowEvent")]

    /**

     *  Dispatched when the previous button is clicked.

     *

     *  @eventType mittal.events.WorkFlowEvent.WORKFLOW_PREVIOUS_CLICK

     * 

     *  @langversion 3.0

     *  @playerversion Flash 10

     *  @playerversion AIR 1.5

     *  @productversion Flex 4

     */

    [Event(name="prevClicked", type="mittal.events.WorkFlowEvent")]

    /**

     *  Dispatched when the work flow item is clicked by user.

     *

     *  @eventType mittal.events.WorkFlowEvent.WORKFLOW_ITEM_SELECTED_BY_USER

     * 

     *  @langversion 3.0

     *  @playerversion Flash 10

     *  @playerversion AIR 1.5

     *  @productversion Flex 4

     */

    [Event(name="workFlowItemClicked", type="mittal.events.WorkFlowEvent")]



    /**

     *  The WorkFlowNavigator component displays a list of workflow items.

     *  Its functionality is similar to the standard work flow component.

     *  Based on the items in data provider it creates a number of work-flow items

     *  and the first and last items will have different representations.

     *  This component is based upon SkinnableComponent and overrides a number of methods.

     *  This class also provides implementation of getCurrentSkinState() method to retrun proper value to its skin class.

     * 

     *  There will not be any scrollbar so proper width and height must be selected.

     *

     *  @langversion 3.0

     *  @playerversion Flash 10

     *  @playerversion AIR 1.5

     *  @productversion Flex 4

     */

    public class WorkFlowNavigator extends SkinnableComponent

    {

        //--------------------------------------------------------------------------

        //

        //  Class constants

        //

        //--------------------------------------------------------------------------

       

        /**

         *  Static constant representing the value "no selection".

         *

         *  @langversion 3.0

         *  @playerversion Flash 10

         *  @playerversion AIR 1.5

         *  @productversion Flex 4

         */

        public static const NO_SELECTION:int = -1;

        private static const DEFAULT_HEIGHT :Number = 200;

        private static const DEFAULT_WIDTH :Number = 200;

        public static const FIRST_ITEM:int = 0;

        private var LAST_ITEM:int;

       

        [SkinPart(required="true", type="mittal.components.WorkFlowButton")]

        /** * A dynamic skin part that defines a WorkFlow Item */

        public var workFlowButton:IFactory;

       

        [SkinPart(required="false")]

        public var nextButton:Button;

        [SkinPart(required="false")]

        public var previousButton:Button;

        [SkinPart(required="true")]

        public var workFlowBar:HGroup;

       

        //--------------------------------------------------------------------------

        //

        //  Constructor

        //

        //--------------------------------------------------------------------------

       

        public function WorkFlowNavigator()

        {

            super();

            addEventhandlers();

            setStyle("skinClass",mittal.skins.WorkFlowNavigatorSkin);

        }

       

        //--------------------------------------------------------------------------

        //

        //  Properties

        //

        //--------------------------------------------------------------------------

       

        /**

         *  @private

         *  Flag that is set when the selectedIndex has been adjusted due to

         *  user interaction or next/prev button click.

         *  This flag is cleared in commitProperties().

         */

        private var selectedIndexChanged:Boolean =  false;

        /**

         *  The 0-based index of the selected item, or -1 if no item is selected.

         *  Setting the <code>selectedIndex</code> property deselects the currently selected

         *  item and selects the data item at the specified index.

         *

         *  <p>The value is always between -1 and (<code>dataProvider.length</code> - 1).

         *

         *  @default -1

         * 

         *  @langversion 3.0

         *  @playerversion Flash 10

         *  @playerversion AIR 1.5

         *  @productversion Flex 4

         */

        private var _selectedIndex:int = NO_SELECTION;

       

        [Bindable("selectedIndexChanged")]

        public function get selectedIndex():int

        {

            return _selectedIndex;

        }

        /**

         *  @private

         */

        public function set selectedIndex(value:int):void

        {

            if(value == _selectedIndex)

                return;

           

            _selectedIndex = value;

            selectedIndexChanged = true;

            invalidateProperties();

        }

        //----------------------------------

        //  hovered

        //----------------------------------

       

        /**

         *  @private

         *  Storage for the hovered property

         */

        private var _hovered:Boolean = false;   

       

        /**

         *  Indicates whether the mouse pointer is over the button.

         *  Used to determine the skin state.

         * 

         *  @langversion 3.0

         *  @playerversion Flash 10

         *  @playerversion AIR 1.5

         *  @productversion Flex 4

         */

        protected function get hovered():Boolean

        {

            return _hovered;

        }

       

        /**

         *  @private

         */

        protected function set hovered(value:Boolean):void

        {

            if (value == _hovered)

                return;

           

            _hovered = value;

            invalidateSkinState();

        }

        /**

         *  @private

         */

        private var dataProviderChanged:Boolean;

        /**

         *  @private

         */

        private var doingWholesaleChanges:Boolean = false;

       

        //----------------------------------

        //  dataProvider

        //----------------------------------

       

        private var _dataProvider:*;

       

        [Bindable("workFlowDataProviderChanged")]

        public function get dataProvider():*

        {

            return _dataProvider;

        }

        public function set dataProvider(value:*):void

        {

            if(_dataProvider == value)

                return;

           

            _dataProvider = value;

            dataProviderChanged = true;

            invalidateProperties();

        }

       

        //--------------------------------------------------------------------------

        //

        //  Methods

        //

        //--------------------------------------------------------------------------

       

        private function nextButtonHandler(event:MouseEvent):void {

            if(selectedIndex < (workFlowBar.numElements -1))

                selectedIndex++;

            dispatchEvent(new WorkFlowEvent(WorkFlowEvent.WORKFLOW_NEXT_CLICK));

        }

        private function previousButtonHandler(event:MouseEvent):void {

            if(selectedIndex > 0)

                selectedIndex--;

            dispatchEvent(new WorkFlowEvent(WorkFlowEvent.WORKFLOW_PREVIOUS_CLICK));

        }

        /**

         *  This method  will deselect all the button except the one clicked by the user.

         * 

         *  @langversion 3.0

         *  @playerversion Flash 10

         *  @playerversion AIR 1.5

         *  @productversion Flex 4

         */

        private function updateSelectedWorkFlowItem(btnIndex:uint):void

        {

            //Enable the selected one and disable the others.

            var totalWorkFlowItems:int = workFlowBar.numElements;

            var workFlowItem:WorkFlowButton;

            for (var i:int = 0; i<totalWorkFlowItems; i++)

            {

                workFlowItem = workFlowBar.getElementAt(i) as WorkFlowButton;

                workFlowItem.isDown = true;

                workFlowItem.invalidateSkinState();

            }

            (workFlowBar.getElementAt(btnIndex) as WorkFlowButton).isDown = false;

        }

        /**

         *  When user clicks on workflowItem the selectedIndex is updated and then same event is

         *  forwarded to the user.

         * 

         *  @langversion 3.0

         *  @playerversion Flash 10

         *  @playerversion AIR 1.5

         *  @productversion Flex 4

         */

        private function workflowItemManualSelectionHandler(event:WorkFlowEvent):void

        {

            selectedIndex = (event.buttonIndex != -1)?(event.buttonIndex):0;

            dispatchEvent(event.clone());

        }

        /**

         *  This method mainly converts the item to workflow item and then calls up addProperWorkFlowItem to add this item.

         * 

         *  @langversion 3.0

         *  @playerversion Flash 10

         *  @playerversion AIR 1.5

         *  @productversion Flex 4

         */

        protected function createAndAddProperWorkFlowItems(item:*, index:int):void

        {

            var workFlowItem:WorkFlowItem;

           

            if(item is WorkFlowItem)

            {

                addProperWorkFlowItem(item, index);

            }

            else if(item is String)

            {

                workFlowItem = new WorkFlowItem();

                workFlowItem.label = item;

                workFlowItem.id = "11";

                addProperWorkFlowItem(workFlowItem, index);

            }

        }

        /**

         *  This method mainly does the actual insertion of work flow item.

         * 

         *  @langversion 3.0

         *  @playerversion Flash 10

         *  @playerversion AIR 1.5

         *  @productversion Flex 4

         */

        protected function addProperWorkFlowItem(item:WorkFlowItem, index:int):void

        {

            var workFlowItem :WorkFlowButton = createDynamicPartInstance("workFlowButton")as WorkFlowButton;

            workFlowItem.label = item.label;

            workFlowItem.id = item.id;

            workFlowItem.btnIndex = index;

            workFlowItem.toolTip = item.label;

           

            if(index == FIRST_ITEM)

            {

                workFlowItem.setStyle("skinClass",mittal.skins.FirstButtonSkin);

            }

            else if (index == LAST_ITEM)

            {

                workFlowItem.setStyle("skinClass",mittal.skins.LastButtonSkin);

            }

            else

            {

                workFlowItem.setStyle("skinClass",mittal.skins.MiddleButtonSkin);

            }

            workFlowBar.addElement(workFlowItem);

        }

        /**

         *  This method is called upon when dataprovider changes. This function will remove all previous items and

         *  insert new items.

         * 

         *  @langversion 3.0

         *  @playerversion Flash 10

         *  @playerversion AIR 1.5

         *  @productversion Flex 4

         */

        protected function refreshWorkFlowItems(itemsCollection:ArrayCollection):void

        {

            var itemsCount:int = itemsCollection.length;

            if(itemsCount > 2)

            {

                for(var index:int = 0; index<itemsCount; index++)

                {

                    createAndAddProperWorkFlowItems(itemsCollection.getItemAt(index),index);

                }

            }

            else

                Alert.show("Please provide atleast 3 items.","Error in Usage");

        }

        /**

         *  This method should be used to perform all clean up operations.

         * 

         *  @langversion 3.0

         *  @playerversion Flash 10

         *  @playerversion AIR 1.5

         *  @productversion Flex 4

         */

        protected function destroyWorkFlow():void

        {

            removeEventHandlers();

        }

        /**

         *  This method handles the mouse events, calls the <code>clickHandler</code> method

         *  where appropriate and updates the <code>hovered</code> and

         *  <code>mouseCaptured</code> properties.

         *

         *  <p>This method gets called to handle <code>MouseEvent.ROLL_OVER</code>,

         *  <code>MouseEvent.ROLL_OUT</code>, <code>MouseEvent.MOUSE_DOWN</code>,

         *  <code>MouseEvent.MOUSE_UP</code>, and <code>MouseEvent.CLICK</code> events.</p>

         *

         *  @param event The Event object associated with the event.

         * 

         *  @langversion 3.0

         *  @playerversion Flash 10

         *  @playerversion AIR 1.5

         *  @productversion Flex 4

         */

        protected function mouseEventHandler(event:Event):void

        {

            var mouseEvent:MouseEvent = event as MouseEvent;

            switch (event.type)

            {

                case MouseEvent.ROLL_OVER:

                {

                    hovered = true;

                    break;

                }

                   

                case MouseEvent.ROLL_OUT:

                {

                    hovered = false;

                    break;

                }

            }

        }

        /**

         *  @private

         */

        private function addEventhandlers():void

        {

            addEventListener(MouseEvent.ROLL_OVER, mouseEventHandler);

            addEventListener(MouseEvent.ROLL_OUT, mouseEventHandler);

        }

        /**

         *  @private

         */

        private function removeEventHandlers():void

        {

            removeEventListener(MouseEvent.ROLL_OVER, mouseEventHandler);

            removeEventListener(MouseEvent.ROLL_OUT, mouseEventHandler);

        }



        //--------------------------------------------------------------------------

        //

        //  Overridden Methods

        //

        //--------------------------------------------------------------------------

        /**

         *  @private

         */

        override protected function measure():void

        {

            super.measure();

            measuredMinHeight = measuredHeight = DEFAULT_HEIGHT;

            measuredMinWidth = measuredWidth = DEFAULT_WIDTH;

        }

        /**

         *  @private

         */

        override protected function commitProperties():void

        {

            if(selectedIndexChanged)

            {

                selectedIndexChanged = false;

                updateSelectedWorkFlowItem(selectedIndex);

                dispatchEvent(new WorkFlowEvent(WorkFlowEvent.SELECTED_INDEX_CHANGED));

            }

            if(dataProviderChanged)

            {

                dataProviderChanged = false;

                LAST_ITEM = IList(dataProvider).length -1;

                refreshWorkFlowItems(dataProvider);

                dispatchEvent(new WorkFlowEvent(WorkFlowEvent.WORKFLOW_DATA_CHANGED));

            }

            super.commitProperties();

        }

        /**

         *  @private

         */

        override protected function partAdded(partName:String, instance:Object):void {

            super.partAdded(partName, instance);

           

            if (instance == nextButton) {

                (instance as Button).addEventListener(MouseEvent.CLICK, nextButtonHandler);

            }

            if (instance == previousButton) {

                (instance as Button).addEventListener(MouseEvent.CLICK, previousButtonHandler);

            }

            if(partName == 'workFlowButton'){

                Button(instance).addEventListener(WorkFlowEvent.WORKFLOW_ITEM_SELECTED_BY_USER,workflowItemManualSelectionHandler);

            }

        }

        /**

         *  @private

         */

        override protected function partRemoved(partName:String, instance:Object):void {

            if (instance == nextButton) {

                (instance as Button).removeEventListener(MouseEvent.CLICK, nextButtonHandler);

            }

            if (instance == previousButton) {

                (instance as Button).removeEventListener(MouseEvent.CLICK, previousButtonHandler);

            }

            if(partName == 'workFlowButton'){

                Button(instance).removeEventListener(WorkFlowEvent.WORKFLOW_ITEM_SELECTED_BY_USER,workflowItemManualSelectionHandler);

            }

            super.partRemoved(partName, instance);

        }

        /**

         *  @private

         */

        override protected function getCurrentSkinState():String

        {

            if (!enabled)

                return "disabled";

           

            if (hovered)

                return "over";

           

            return "up";

        }

       

    }

}



Every workflow item is represented by  WorkFlowButton as:





package mittal.components

{

    import flash.events.Event;

    import flash.events.MouseEvent;

   

    import mittal.events.WorkFlowEvent;

    import mittal.skins.FirstButtonSkin;

   

    import spark.components.Button;

   

    /**

     *  Dispatched when user clicks on any of the WorkFlow Item (Button). This will require the selectedIndex property of the navigator to be updated.

     *

     *  @eventType mittal.events.WorkFlowEvent.WORKFLOW_ITEM_SELECTED_BY_USER

     * 

     *  @langversion 3.0

     *  @playerversion Flash 10

     *  @playerversion AIR 1.5

     *  @productversion Flex 4

     */

    [Event(name="workFlowItemClicked", type="mittal.events.WorkFlowEvent")]

   

    public class WorkFlowButton extends Button

    {

        private var _btnIndex:uint;

        public var isDown:Boolean;

       

        [Bindable(event="workFlowItemIndexChanged")]

        public function get btnIndex():uint

        {

            return _btnIndex;

        }

        public function set btnIndex(value:uint):void

        {

            if(value == btnIndex)

                return;

            _btnIndex = value;

            dispatchEvent(new Event("workFlowItemIndexChanged"));

        }

        public function WorkFlowButton()

        {

            setStyle("skinClass",FirstButtonSkin);

            addEventListener(MouseEvent.CLICK, mouseClickHandler);

            super();

        }

        protected function mouseClickHandler(event:MouseEvent):void

        {

            //It need not to do any skin change as this would be done automatically once selectedIndex of navighator is set.

            event.preventDefault();

            event.stopImmediatePropagation();

            dispatchEvent(new WorkFlowEvent(WorkFlowEvent.WORKFLOW_ITEM_SELECTED_BY_USER,btnIndex));

        }

        override protected function commitProperties():void

        {

            super.commitProperties();

        }

        override protected function getCurrentSkinState():String

        {

            return (isDown ? 'buttonDown' : super.getCurrentSkinState());

        }

    }

}




I have used six skins: One for the First Button, One for Middle buttons, One for the Last Button, One for Next Button, One for Previous Button and One for the WorkFlowNavigator component. The skin for the First Button will be like below. The important thing to note is the HostComponent and Path tag used to create the shape.


<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"

             xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minWidth="21" minHeight="21" alpha.disabled="0.5">

   

    <!-- host component -->

    <fx:Metadata>

        <![CDATA[

        /**

         * @copy spark.skins.spark.ApplicationSkin#hostComponent

         */

        [HostComponent("mittal.components.WorkFlowButton")]

        ]]>

    </fx:Metadata>

   

    <!-- states -->

    <s:states>

        <s:State name="up" />

        <s:State name="over" />

        <s:State name="down" />

        <s:State name="disabled" />

        <s:State name="buttonDown" />

    </s:states>

   

    <s:Graphic>

        <s:Path data="m 0 0

                h 100

                l 20 20

                l -20 20

                h -100

                v -40">

            <s:fill>

                <s:LinearGradient rotation="90">

                    <!-- Note the use of different colors based on state -->

                    <s:GradientEntry color="0xfd1901" color.buttonDown="0xAF220D" />

                    <s:GradientEntry color="0xa70d12" color.buttonDown="0xAF220D" />

                </s:LinearGradient>

            </s:fill>

            <s:stroke>

                <s:SolidColorStroke color="0xAF220D" weight="1" alpha=".8" alpha.disabled="0"  alpha.up="0"/>

            </s:stroke>

        </s:Path>

    </s:Graphic>

   

    <!-- layer 8: text -->

    <!--- @copy spark.components.supportClasses.ButtonBase#labelDisplay -->

    <s:Label id="labelDisplay"

             textAlign="left"

             verticalAlign="middle"

             maxDisplayedLines="1"

             color="white"

             horizontalCenter="0" verticalCenter="1"

             left="0" right="10" top="8" bottom="2">

    </s:Label>

   

</s:SparkSkin>



And finally this component will be used as:


<fx:Script>

        <![CDATA[

            import mittal.events.WorkFlowEvent;

           

            import mx.collections.ArrayCollection;

            import mx.controls.Alert;

            private function creationComplete():void

            {

                wf.dataProvider = new ArrayCollection(["one", "two", "three", "four", "five","six","seven","eight","nine","ten"]);

            }

            protected function bd_workFlowItemClickedHandler(event:WorkFlowEvent):void

            {

                Alert.show("Item clicked"+ event.buttonIndex);

            }



        ]]>

    </fx:Script>

    <s:layout>

        <s:VerticalLayout/>

    </s:layout>

    <components:WorkFlowNavigator id="wf" width="100%" height="60"

                                  workFlowItemClicked="bd_workFlowItemClickedHandler(event)"

                                  />



I have not been able to find a proper way of highlighting actionscript code and we also dont have an option to upload source code, so I have provided the complete source folder here.

This workflow resembles to some extent the workflow component we get in google blogger itself when we explore setting etc. So Did you find this post helpful? What would you like to be improved/added? Please spent some time to provide your feedback that can help improve it.



Wednesday, February 15, 2012

Good Flex Interview Questions [Flex Basics]

Well let me clarify one thing: This post is not exhaustive list of Flex interview questions. Rather there can be no post covering all possible interview questions for any technology. I have experienced the lack of good interview questions for Flex on web, so I have created this post.

I have taken interview of Flex developers (ranging 3 to 8 years experience) and have asked different questions (obviously based on experience things change). I too have attended many interviews so thought about writing-down some good flex interview questions. So Lets start :).

Question: What is Flex? 
Answer: Flex is an application framework (yes it is a framework!!) that allows developers to build rich applications for desktop (using AIR), web, mobiles and tablets (iOS, android, blackberry etc). The web applications (SWF Files) run in Flash Player which is available in more than 90% computers across the world. For desktop-based applications AIR is needed. There are two main building blocks for development in Flex: ActionScript (used mainly for Logic part) and MXML (used mainly for declaration of tags and components etc). More can be read here:
http://en.wikipedia.org/wiki/Adobe_Flex
http://flex.org/what-is-flex/
http://stackoverflow.com/questions/59083/what-is-adobe-flex-is-it-just-flash-ii
http://www.adobe.com/devnet/flex/videotraining.html

Question: What are the differences between Flex 3 and Flex 4?
Answer: There can be lot of syntactic or other differences between the two, but major difference is: In Flex 4 the architecture of components (most of) have got changed. These components (called Spark the older ones in Flex 3 are called Halo) have separated the role of developer and designer. Spark components have one main core component class (written in actionscript) that contains the main logical part and one Skin class that handles all the visual aspects. We can say core component is skeleton and skin is its visual appearance. For example spark button has one core Button class and one skin class for it. More can be read here:
http://www.adobe.com/devnet/flex/articles/flex3and4_differences.html
http://blog.everythingflex.com/2009/05/12/flex-3-vs-flex-4-state-management/

Question: What are the advantages and disadvantages of using Flex? And why Flex wins over other technologies?
Answer: Flex is very mature component-based development framework that reduces the development time and gives very good results. There are plenty of advantages: Easy to learn, Flash Player available widely, Works really well with other back-end technologies (specially with java), based on components so very easy to debug and fix, also has a very good IDE etc. The disadvantages are: applications used to be slightly heavy etc. But all of them can be handled to a good extent by following up best-practices and good application architecture. More can be read here:
http://www.anandvardhan.com/2007/06/26/top-10-reasons-why-flex-wins-against-silverlight/
http://techadam.wordpress.com/2009/07/08/advantages-and-disadvantages-of-flex/

If you want to read about Flex architecture then there are some good posts already on the net:
http://www.dehats.com/drupal/?q=node/32
http://www.adobe.com/devnet/flex/architecture.html




Well now we will move to other basic questions about Flex.

Question: What are the characteristics of a constructor in action script?
Answer: The main characteristics are:
1. No return Type
2. Should be declared public
3. Might have optional arguments.
4. Cannot have any required arguments if we use it as an MXML tag
5. Calls the super() method to invoke the superclass’s constructor.
If we do not define a constructor, the compiler inserts one for us and adds a call to super().
However, it is considered a best practice (not compulsion) to write a constructor and to explicitly
call super(), unless the class contains nothing but static members. If we define the constructor,
but omit the call to super(), Flex automatically calls super() at the beginning of our constructor.

Question: What is the difference between Viewstack vs Viewstate?
Answer: Actually ViewStack and ViewState are not related. View states give one way to change
the look and feel of a component in response to user action. We can also use navigation
container e.g. Acordion, ViewStack, Tab navigator etc. Choice of selecting navigation container or
states depends upon requirement of application.
1. View stack is a component used to display different views (normally different data), one
at a time. View states are related views of a single set of data. For example normal view
and advanced view for a image.
2. In ViewStack components can not be shared easily between the different views, they had
to be created each time view is changed. For example if we want a search box in every
view, then it has to be created in every view. States work with transitions. We can apply
various changes to a same component in various states. They will appear according to
states.

Question : Can we have overloading in action script?
Answer: Overloading is not allowed in action script. What we can do is to use – default argument
or rest (….) parameter.
public function foo(arg1:Object = null, arg2:Object = null)
{
}
public function foo(arg1:String, ...args)
{
}




Question : What are the differences and similarities in Action script and Java?
Answer:
Similarities: Both Action Script and Java are
Object Oriented
Use Single Inheritance
Have a Base Object Class
Use strongly typed variables
Have Packages, Classes and interfaces
Support Public, Protected and Private methods and variables
Support static functions and variables
Support try/ catch/ finally blocks for exception handling
Differences: Action Script Java
AS has get/set methods.
AS supports dynamic classes.
AS supports closure functions.
AS supports optional functional arguments.
AS doesn’t allow private classes or constructors.
AS doesn’t have any support for overloading but Java has good support for it.

Question: What is a metadata tag?
Answer: These tags provide information to Flex compiler regarding the usage of our component. Examples are Bindable, Event, DefaultProperty, Inspectable etc.

Question: Does Exclude or ExcludeClass really excludes the data or class?
Answer: Exclude(and ExcludeClass) tags simply influence the set of choices that are available
in Flex Builder. They don’t exclude the classes from linking, which is a general misconception.
There are MXML options to say “I want to treat this symbol as exteranally defined” . Depending
on how we compile our application, generally the classes that are included are those that are
referenced from the root application or classes, either directly or via some other class that is
referenced directly or not from the root application or classes. The -link-report mxmlc option is
very useful in that it tells us 1) what all is in our swf, and 2) who depended on each class to cause
it to be included.

Question: Can we define a constructor for MXML?
Answer: NO, if we do compiler throws an error. For many components we can write event
listeners and we can use them instead of constructor. For example depending upon the
component we can write listener for preinitialize, initialize and creationComplete.
These events are defined by UIComponent class and inherited by all its sub classes. If we
create an MXML component then that is not a sub class of UIComponent. Therefore we cannot
take advantage of that. But we can implement IMXMLObject interface and then implement the
IMXMLObject.initialized() method. Flex calls this method after it initializes the properties
of the component.

<!-- mxmlAdvanced/myComponents/ObjectComp.mxml -->

<mx:Object xmlns:mx="http://www.adobe.com/2006/mxml"

implements="mx.core.IMXMLObject">

<mx:Script>

<![CDATA[

// Implement the IMXMLObject.initialized() method.

public function initialized(document:Object, id:String):void

{

trace("initialized, x = " + x);

}

]]>

</mx:Script>

<mx:Number id="y"/>

<mx:Number id="z"/>

<mx:Number id="x"/>

</mx:Object>

Question: Give some idea of Class Hierarchy Diagram? (Yet to update)
Answer: The class hierarchy diagram is shown below. One point that needs attention is
UIComponent inherits from FlexSprite class (not shown) which adds nothing more than a
toString() method.



Question: What is a filter function?
Answer: We use this function to limit the data view in the collection to a subset of source data
object. The function must take a single Object parameter, which corresponds to a collection item,
and must return a Boolean value specifying whether to include the item in the view.




Question: What is a view cursor?
Answer: A cursor is a position indicator; it points to a particular item in the collection. We use
view cursor to traverse items in a collection’s data view and modify the data in collection. A view
cursor includes following methods –
1. The moveNext() and movePrevious() to move the cursor forward or backward. Use
beforeFirst or afterLast properties to check whether we have reached the bounds.

2. The findAny(), findFirst() and findLast() methods move the cursor to an item
that matches the parameter.

Question: What events are used by the Collections?
Answer: Collections dispatch CollectionEvent, PropertyChangeEvent and FlexEvent objects.
 Collections dispatch a CollectionEvent when there is a change in collection. The
property kind for a CollectionEvent object can be used to find which kind of change
occurred. This property is compared against CollectionEventKind constants to find
what the change was for example, UPDATE etc.
 The CollectionEvent object includes an items property that is an array of objects. For
ADD and REMOVE kind events this contains added or removed items, but for UPDATE it
contains an array of PropertyChangeEvent objects.
 PropertyChangeEvent class has kind property to indicate the way in which property
changed. This can be determined by comparing kind property with
PropertyChangeEventKind constants, for example UPDATE. This event object also has
properties to indicate the values before and after the change.
 View cursor objects dispatch a FlexEvent with type property
mx.events.FlexEvent.CURSOR_UPDATE when the cursor position changes.

Question: What is the use of disableAutoUpdate method?
Answer: This method prevents the events that represent changes to the underlying data from
being broadcasted by the view. It also prevents collection from being updated. This method is
useful where multiple items in collection are being edited at once. By disabling the auto update
the changes are received as a batch instead of multiple events. Also in a DataGrid this method
prevents update to the collection while a specific item is selected. When item is no longer
selected the DataGrid controls calls enableAutoUpdate() method.

Question: What coordinate systems are supported by Flex?
Answer: Three – global, local and content. Global are with respect to the upper-left corner of
Stage in Adobe Flash Player and Adobe® AIR™. Local coordinates are relative to the upper-left
corner of the component. Content coordinates are relative to the upper-left corner of the
component's content.


When we use local coordinates reported in a event object, such as MouseEvent localX and
locallY properties these values are mouse coordinates relative to event target. The target may
be a subcomponent e.g. UITextField, in a Button component and not Button itself. In such cases
we must convert local coordinates into global coordinate system and then convert global to
content coordinate system. All Flex components provide two read-only properties
contentMouseX and contentMouseY and six methods to convert in between the coordinates
e.g. contentToGlobal, contentToLocal etc.


<!-- containers\intro\MousePosition.mxml -->

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"

backgroundColor="white">

<mx:Script>

<![CDATA[

import mx.controls.Alert;

// Handle the mouseDown event generated

// by clicking in the application.

private function handleMouseDown(event:MouseEvent):void {

/* Convert the mouse position to global coordinates. The localX and

localY properties of the mouse event contain the coordinates at which

the event occurred relative to the event target, typically one of the

colored internal Canvas controls. A production version of this example

could use the stageX and stageY properties, which use the global

coordinates, and avoid this step. This example uses the localX and

localY properties only to illustrate conversion between different

frames of reference.*/

var pt:Point = new Point(event.localX, event.localY);

pt = event.target.localToGlobal(pt);

// Convert the global coordinates to the content coordinates

// inside the outer c1 Canvas control.

pt = c1.globalToContent(pt);

// Figure out which quadrant was clicked.

var whichColor:String = "border area";

if (pt.x < 150) {

if (pt.y < 150)

whichColor = "red";

else

whichColor = "blue";

}

else {

if (pt.y < 150)

whichColor = "green";

else

whichColor = "magenta";

}

Alert.show("You clicked on the " + whichColor);

}

]]>

</mx:Script>

<!-- Canvas container with four child Canvas containers -->

<mx:Canvas id="c1"

borderStyle="none"

width="300" height="300"

mouseDown="handleMouseDown(event);">

<mx:Canvas

width="150" height="150"

x="0" y="0"

backgroundColor="red">

<mx:Button label="I'm in Red"/>

</mx:Canvas>

<mx:Canvas

width="150" height="150"

x="150" y="0"

backgroundColor="green">

<mx:Button label="I'm in Green"/>

</mx:Canvas>

<mx:Canvas

width="150" height="150"

x="0" y="150"

backgroundColor="blue">

<mx:Button label="I'm in Blue"/>

</mx:Canvas>

<mx:Canvas

width="150" height="150"

x="150" y="150"

backgroundColor="magenta">

<mx:Button label="I'm in Magenta"/>

</mx:Canvas>

</mx:Canvas>

</mx:Application>

There are many topics touched during interview: Event, Binding, Datagrid and other visual components, Item Renderer, Item Editor, Component Lifecycle, Custom Component Creation, Functions to override, Styling and Skinning, etc etc etc.




Lets start with Event. This simple topic can have a plethora of questions.Some of them are below:

What is an Event? 
Why do we need Events? 
What are its different phases?
What are the target and currentTarget properties? 
During which phase these two point to same component?
Which function is responsible for setting the target property of an event?
 How can we catch an event during capture and bubble phase? 
What is a cancellable event? 
Why does preventDefault () not work with all the events?
What are the differences between stopPropagation() and stopImmediatePropagation()?
Why do we use updateAfterEvent() with MouseEvent types?
What is an event listener? How can we add event listeners in action script and MXML? 
What is the use of 'useWeakReference' parameter in addEventListener() function?
How can we pass additional parameters when we add a listener using action-script?
What are the differences between creationComplete() and applicationComplete() events?

Why do we need to remove an event listener if we have added it? 
Why adding an event listener in actionscript better than adding using MXML?
Why do we need Event metadata tag and why we need to use this while writing custom Component?
Can we have multiple listeners for single event? 
Can we have multiple events and single listener?
What is a custom event and why do we need it?
What is a Display List and how event traverses in it?
Why do we need to implement clone() and toString() method for our custom event?

What are the best practices for custom event?
What is an EventDispatcher class? Why do we extend this class sometimes?
How can we define inner event listener or closure function?

This is simply a tip of iceberg. There is no short cut. I have answered all these questions here.




Next good topic is Binding. This is the topic where even experienced developers get confused. Some of the good questions in Binding are:

What is an Binding? 
Why do we need data binding and when it happens?
What are bindable getter and setters?
What event is by default dispatched by bindable getters/setter?
What is difference between [Binding] , [Binding("eventName")]
Why do we need to specify and dispatch event in bindable getters/setters?
What are read-only and write-only properties? What is the need of them?
What are the five main  ways of using Binding?
How to use data bindign with data model?
How can we define Binding in MXML and ActionScript? Which one is better?
Can we bind a single source to more than one destinations?
What are implicit and explicit binding techniques?
What is bi-directional or two-way binding?
What are the problem with using curly braces for Binding?
What is a change watcher and how to use it?
What is the importance of 'useWeakReference' in BindingUtils.bindSetter() method?
How can we bind an object?
Why binding does not get triggerd while changing attributes of an bindable Object?
When shall we use ObjectProxy rather than Object for Binding?
How can we create a Bindable Object?
Difference between compile time vs runtime binding?
How to use Bindable Metadata tag?
What is bindable working chain and how does it work?
What is trubo Binding and what problems does it solve?


Again this is not an exhaustive list. There is no short cut. I have answered all these questions in three parts here


Question: What is an ItemRenderer and how does it work?
Answer: In very simple terms an item renderer is something that  renders an item. An item basically is a value-object in most of the cases. Suppose we want to show the sales records for 15 items. We may keep a variable growth index which vary from +5 to -5 representing extreme growth (+5), neutral (0) and extreme decline (-5) in sales. Then rather than showing these value as one of the column in a datagrid we may better like to show images for thumbs-up (+5), thumbs down (-5) and a dash for neutral. So this is one scenario where it may be helpful. So we need one box or something to take our value inside and then show proper image. That something is item-renderer. 

Now if we have 10,000 records and at any moment of time only 25 are visible then it does not make sense to have 10,000 item-renderers as it can be a performance issue. Flex creates only those many item-renderers those are needed (In our example 25 + some more). Then when user scrolls the items/records and when new set of records are visible the old item-renderers are re-used.  We can forcefully ask Flex to create 10,000 item-renderers also by setting one variable useVirutalLayout to false (by default it is true). In Flex 4 easiest way is to extend ItemRenderer class. A Datagrid by default uses a Label as item renderer. You can read some best practices here.

Question: How an ItemRenderer is different from ItemEditor? Can we use an ItemRenderer as ItemEditor as well?

Answer: If ItemRenderer is used to render (show), ItemEditor is used to edit. This is handy in may situations. Consider our rating example only: If user wants to assign some rating then we may allow him to rate 0 to 5. When ever he will select any record to change the rating he would click on existing rating (a label). When he clicks item edit will begin, then we can show a drop-down havign values from 0 to 5 the moment user selects the value (valueCommit event) it will be assigned and replace the old value. We can also use renderer as an editor (for example for datagrid) as well by setting property rendererIsEditor to true.





Question: What is a dynamic class? And how it is different from a sealed class?
Answer: dynamic class defines an object that can be altered at run time by adding or changing properties and methods. A class that is not dynamic, such as the String class, is a sealedclass. You cannot add properties or methods to a sealed class at run time.
dynamic class Protean

{
    private var privateGreeting:String = "hi";
    public var publicGreeting:String = "hello";
    function Protean()
    {
        trace("Protean instance created");
    }
}

Part Two here.

So Did you find this post helpful? What would you like to be improved/added? Please spent some time to provide your feedback that can help improve it.