Tuesday, November 18, 2008

How to test if an object is of a given type?

When dealing with typeCasting its essential to test if the objects are compatible before having a
typecast statement.Forgetting to do this results in fragile code that might throw a type cast error anytime.
Here is an example that shows you how to test this.
Note:A child is a type of parent and the vice versa is not true.


<?xml version="1.0" encoding="utf-8"?>

<mx:Application

creationComplete="test()"

xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

<mx:Script>

<![CDATA[

import mx.controls.Alert;

import mx.events.CollectionEvent;

import mx.collections.ArrayCollection;

private function test():void {

var parent:Parent = new Parent();

var child:Child = new Child();

if (child is Parent) {

Alert.show("Yes");

} else {

Alert.show("No");

}

}

]]>

</mx:Script>

</mx:Application>

}




Bookmark and Share

Flex - Check if a property exists in an Object

When dealing with typeCasting its essential to test if the objects are compatible before having a
typecast statement.Forgetting to do this results in fragile code that might throw a type cast error anytime.
Here is an example that shows you how to test this.

Note:A child is a type of parent and the vice versa is not true.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
creationComplete="test()"
xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.CollectionEvent;
import mx.collections.ArrayCollection;

private function test():void {
var parent:Parent = new Parent();
var child:Child = new Child();

if (child is Parent) {

Alert.show("Yes");

} else {

Alert.show("No");

}

}

]]>

</mx:Script>

</mx:Application>

}



Bookmark and Share

Monday, November 17, 2008

Understanding [Bindable]

One of the most tricky and less understood features of flex is Binding.

Sure binding on first sight, is a very simple concept to grasp , but when one tries to apply it practically , one can have himself pulling his hair out.

Read this before you become a virendar sehwag look alike J.

 

My first doubts on the way [Bindable] arouse when I tried to use the bindable variable on an expression .

I was just wondering if having an expression based on a bindable variable would recompute itself , whenever the variable changed?

I had something like this

 

[Bindable]

private var test:Number = new Number();

 

private function changeText():void {

            this.test=new Number(nameInput.text);

                 }

 

And I set the value of the bindable variable on button click

 

<mx:HBox width="100%">

                        <mx:Form>

                                   <mx:FormItem label="valueOfTest">

                                                <mx:TextInput id="nameInput" width="100"/>

                                    </mx:FormItem>

 

                                    <mx:FormItem label="Check the Binding effect here">     

                                                <mx:TextInput id="valueAfterChange" text="{test > 1}" width="100"/>

                                    </mx:FormItem>

 

                                    <mx:FormItem>

                                                            <mx:Button label="Set" click="changeText()"/>

                                    </mx:FormItem>

 

The value of the second text input did change and the expression was recomputed.

Cool enough. When I removed the [Bindable] metatag the value did not change.That was expected~.

The fact is that the events are not triggered on components that use the variable.Simple.

 

Now, what if you have an function that is assigned to the text attribute of the second text input?

 

See this,

I changed the second text inputs definition to

 

<mx:TextInput id="valueAfterChange" text="{getTextForMe() }" width="100"/>

 

And I added the function which goes like this

                                    private function getTextForMe():Number {

 

                                                return test + 10;

 

                                    }

 

My first instinct was that the value would automatically be recomputed , but it did not.

It turns out that the function should be declared as [Bindable] too, so that the property would be recomputed too.

                                   

                                    [Bindable]

                                    private function getTextForMe():Number {

                                                return test + 10;

                                    }

 

 

 

Alright so here is the moral of the story.

 

Have your variables annotated with [Bindable] meta tag whenever the changes to it has to reflect elsewhere.

Changes to variables that are bindable will reflect even if the variable was used in an arithematic expression. I mean any property that uses the bindable variable to compute, its value will be recomputed.

If you are using functions to determine value for  any property that uses the bindable variable , have the function declared as bindable.

 

 

Hope it helps I did actually stop you from becoming a virendar sehwag llok alike J




Bookmark and Share

Friday, November 14, 2008

Watch for Changes in an ArrayCollection

ArrayCollection is one of the most beautiful aspects of flex which makes it what it is. When dealing with ArrayCollections, one may want to have some kind of a callback when the items are changed.

This is how you can do it.

The magic lies in  flash.events.Event.CollectionEvent. To detect a change just add a listener to the CollectionEvent.COLLECTION_CHANGE on the arrayCollection.

Even if your array collection is not bindable, this is a sure shot way to get notified of changes made to the array collection.

NOTE:The event will be triggered only when you add or delete items from the array collection and not when it is re assigned or re initialized  and not when you change the values of item within.

 

Here is the example:

 

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    creationComplete="setUpListeners()"
     xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import mx.events.CollectionEvent;
            import mx.collections.ArrayCollection;
            private var testAC:ArrayCollection = new ArrayCollection();
           
            private function setUpListeners():void {
                testAC.addEventListener(CollectionEvent.COLLECTION_CHANGE,showChange);
            }
            private function changeArrayCollection():void{               
                var obj:Object = new Object();
                obj.name=nameInput.text;
                obj.age=ageInput.text;
                testAC.addItem(obj);
                //var temp:ArrayCollection = new ArrayCollection();
                //temp.addItem(new Object());               
                //testAC=temp; Will not trigger!
                //Note:testAC=new ArrayCollection(); Will not trigger!
               
            }
            private function showChange(eve:CollectionEvent):void {
                Alert.show("Collection Changed.Operation was of type->"+ eve.kind
                + "at location-> " + eve.location);
               
            }
        ]]>
    </mx:Script>   
    <mx:HBox width="100%">
        <mx:Form>
            <mx:FormItem label="name">
                <mx:TextInput id="nameInput" width="100">
                   
                </mx:TextInput>               
            </mx:FormItem>
            <mx:FormItem label="age">
                <mx:TextInput id="ageInput" width="100">
                   
                </mx:TextInput>               
            </mx:FormItem>
            <mx:FormItem>
                <mx:Button label="change" click="changeArrayCollection()">
                   
                </mx:Button>
            </mx:FormItem>
        </mx:Form>
       
    </mx:HBox>
</mx:Application>
 

Hope it helps!!       

        

 

 

 

 





Bookmark and Share

Thursday, November 13, 2008

Hide Show a Tab on Tab Navigator

Right, just a short code-snippet I'd like to share for those who have been searching for a solution for ages (like I have). I was looking for a way to hide specific tabs in a TabNavigator in Flex 3 without removing a child form the ViewStack

This is not possible by simply hiding a child in the viewstack (child.hide = true) or by setting its visibility to false (child.visible = false). 

With an easy workaround you can set the visiblity of a specific tab to false: 

tabNavigator.getTabAt(1).visible = false;

Probably more people have found this solution, but I couldn't find it on the web so here it is.

 





Bookmark and Share

How to copy an ArrayCollection

 

There are many ways to copy an arrayCOllection to another one.Here is a couple of them

Initialize the new array with the older arrayCollection's source.

Example :var a : ArrayCollection = new ArrayCollection(array);   var b : ArrayCollection = new ArrayCollection(a.source);

Use mx.utls.ObjectUtil.Copy

Example :var arrayCollection1 : ArrayCollection = ObjectUtil.copy(arrayCollection2)

Hope it helps!





Bookmark and Share

Proper Form Validation in flex

Validators in flex have always been a mystery and I happened to encounter one of those really upsetting quirks in one of my projects.What I am talking about is the un invited red borders that get visible when you tab out of fields which have validators assigned.One would expect that the error tooltip would also appear when the red borders come.But you know, flex throws some unpleasant surprises at you at times and this is one such thing.Don't contemplate harrikiri yet :-). Every problem has a solution hidden inside it.

 

This is how it looks

 

 

 

            Turns out that the ToolTipManager can help one hiding and showing tooltips as and when requried.

           

            Here is some sample code.

 

            <mx:FormItem label="Your name">

                <mx:HBox>

                    <mx:TextInput id="yourName" change="onChangeText(event);" focusOut="onChangeText(event);"/>                

                </mx:HBox>

            </mx:FormItem>

 

            private function onChangeText(eve:Event):void {

                       

          var target:TextInput = eve.currentTarget as TextInput;

if (target.text == "")

                        {

            // Has the error message ToolTip already been created?

            // (A reference to created ToolTip instances is saved in a hash called errorMessageToolTips.)

                   // Create the ToolTip instance.

        var pt:Point = new Point(target.x, target.y);

        pt = target.contentToGlobal(pt);

        var errorTip:ToolTip = ToolTipManager.createToolTip(errorMessages[target.name] + " cannot be empty", pt.x + target.width + 5, pt.y) as ToolTip;

        errorTip.setStyle("styleName", "errorTip");

        errorTip.visible=true;      

                        }

            }

 

           

 

            Comments Welcome .. As always.       

 





Bookmark and Share