Sunday, October 21, 2012

AS3: Creating a Clone

In the AS3 world, there might be numerous situations that requires you to create a clone of a very complex component of object. However it will be kinda crazy if you are going to run a loop and copy all the variables one by one. Therefore here's a class that will help you to reduce the amount of work needed.

Here's our main Application Class - SimpleCopyingOfObjects.mxml
<?xml version="1.0" encoding="utf-8"?>
<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/mx"
      backgroundColor="#CDCDCD"
      creationComplete="creationCompleteEvent(event)">
 <fx:Script>
  <![CDATA[
   import flash.net.*;
   import flash.utils.*;
   
   import mx.collections.ArrayCollection;
   import mx.events.FlexEvent;
   import mx.utils.ObjectUtil;
   
   import view.CustomComponent;
   
   protected function creationCompleteEvent(event:FlexEvent):void
   {
    //Creating 2 new CustomComponent and assign some
    //values to it.
    var tempObj:CustomComponent = new CustomComponent();
    var tempObj1:CustomComponent = new CustomComponent();
    tempObj.message = "I'm am a new View.";
    tempObj1.message = "I'm am a new View1.";
    tempObj.myContent.addItem(tempObj1);
    
    //Now let's create some clones.
    var tempClone1 = cloneObject(tempObj);
    var tempClone2 = cloneCustomObject(tempObj);
    
    txtMsg.appendText("tempObj is: " + 
     getQualifiedClassName(tempObj));
    txtMsg.appendText("\ntempClone1 is: " + 
     getQualifiedClassName(tempClone1));
    txtMsg.appendText("\ntempClone2 is: " + 
     getQualifiedClassName(tempClone2));
    
    txtMsg.appendText("\n\nValue of tempObj.message is: " + 
     tempObj.message);
    if(tempClone1.hasOwnProperty("message"))
    {
     txtMsg.appendText("\nValue of tempClone1.message is: "+ 
      tempClone1.message);
    }else{
     txtMsg.appendText("\nValue of tempClone1.message is " + 
      "unaccessible.");
    }
    if(tempClone2.hasOwnProperty("message"))
    {
     txtMsg.appendText("\nValue of tempClone2.message is: "+ 
      tempClone2.message);
    }else{
     txtMsg.appendText("\nValue of tempClone2.message is " + 
      "unaccessible.");
    }
    
    tempObj.message = "I'm am a old View.";
    txtMsg.appendText("\n\nChange Value of tempObj.message "+ 
     "to 'I'm am a old View.'");
    txtMsg.appendText("\nValue of tempObj.message is: "+ 
     tempObj.message);
    if(tempClone1.hasOwnProperty("message"))
    {
     txtMsg.appendText("\nValue of tempClone1.message is: "+ 
      tempClone1.message);
    }else{
     txtMsg.appendText("\nValue of tempClone1.message is " + 
      "unaccessible.");
    }
    if(tempClone2.hasOwnProperty("message"))
    {
     txtMsg.appendText("\nValue of tempClone2.message is: "+ 
      tempClone2.message);
    }else{
     txtMsg.appendText("\nValue of tempClone2.message is " + 
      "unaccessible.");
    }
    
    tempObj1.message = "I'm am a old View1.";
    txtMsg.appendText("\n\nChange Value of tempObj1.message "+ 
     "to 'I'm am a old View1.'");
    
    var tempObject:CustomComponent = CustomComponent(
     tempObj.myContent.getItemAt(0));
    txtMsg.appendText("\nValue of tempObj.myContent." +
     "getItemAt(0).message is: " + tempObject.message);
    if(tempClone1.myContent is ArrayCollection)
    {
     if(tempClone1.myContent.getItemAt(0) is CustomComponent)
     {
      tempObject = CustomComponent(
       tempClone1.myContent.getItemAt(0));
      txtMsg.appendText("\nValue of tempClone1.myContent." +
       "getItemAt(0).message is: " + tempObject.message);
     }else{
      txtMsg.appendText("\nValue of tempClone1.myContent." +
       "getItemAt(0) is not a CustomComponent.");
     }
    }else{
     txtMsg.appendText("\nValue of tempClone1.myContent" +
      "getItemAt(0) is unaccessible.");
    }
    if(tempClone2.myContent is ArrayCollection)
    {
     if(tempClone2.myContent.getItemAt(0) is CustomComponent)
     {
      tempObject = CustomComponent(
       tempClone2.myContent.getItemAt(0));
      txtMsg.appendText("\nValue of tempClone2.myContent." +
       "getItemAt(0).message is: " + tempObject.message);
     }else{
      txtMsg.appendText("\nValue of tempClone2.myContent." +
       "getItemAt(0) is not a CustomComponent.");
     }
    }else{
     txtMsg.appendText("\nValue of tempClone2.myContent" +
      "getItemAt(0) is unaccessible.");
    }
   }
   
   //This function will copy an custom object/component
   //into an Object.
   private function cloneObject(CustomObject:*):*
   {
    var ba:ByteArray = new ByteArray();
    ba.writeObject(CustomObject);
    ba.position = 0;
    return ba.readObject();
   }
   
   //This function will clone an custom object/component.
   //based on the given type of the original object.
   private function cloneCustomObject(CustomObject:*):*
   {
    //Grab the Class Name of the object that we are copying
    var className:String = getQualifiedClassName(CustomObject);
    //Register it first before we clone it
    registerClassAlias(className, 
     getDefinitionByName(className) as Class);
    //While copying the object, the Class Type will be register
    //because of the registerClassAlias call previously
    return ObjectUtil.copy(CustomObject);
   }
  ]]>
 </fx:Script>
 <s:VGroup width="100%" 
     height="100%"
     verticalAlign="middle"
     horizontalAlign="center">
  <s:Label textAlign="center" 
     text="Output:"/>
  <s:TextArea width="90%" 
     height="90%"
     id="txtMsg"/>
 </s:VGroup>
</s:Application>
And here's our custom component Class - CustomComponent.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
   xmlns:s="library://ns.adobe.com/flex/spark" 
   xmlns:mx="library://ns.adobe.com/flex/mx" >
 <fx:Script>
  <![CDATA[
   import mx.collections.ArrayCollection;
   private var _message:String = "";

   public function get message():String
   {
    return _message;
   }

   public function set message(value:String):void
   {
    _message = value;
   }
   
   private var _myContent:ArrayCollection = 
    new ArrayCollection();

   public function get myContent():ArrayCollection
   {
    return _myContent;
   }

   public function set myContent(value:ArrayCollection):void
   {
    _myContent = value;
   }
   
  ]]>
 </fx:Script>
</s:Group>
* Click here for the demo shown in this post.
^ Click here for the source files for the demo.

No comments:

Post a Comment