6 Replies Latest reply on Mar 1, 2010 8:40 PM by rickcr

    RemoveChild Errors

    alice_data Level 1

      Hi,

       

        I have the code as in the following, and I am attempting to remove the child, and then create a new one with a different type for a different purpose. The child, however, does not seem to be able to be removed, below is the code:


      package map
      {
          import com.zavoo.svg.*;    
          import flash.display.Sprite;
          import flash.events.Event;    
           import mx.containers.Canvas;
           import mx.core.UIComponent;

       

          public class SvgMap extends UIComponent {
             
          public var canvas:Sprite;
              [Embed(source="USA_Counties_with_FIPS_and_names.svg")]
              public var usaMap:Class;
          private var horizontal_bar:Canvas;
         
          public function SvgMap():void {
                 
              canvas = new usaMap();
              canvas.width = 650;
                      canvas.height = 500;
                      addChild(canvas); 
                      trace(canvas.parent); //Prints out SvgMap0 SvgMap4 SvgMap7                            
      }
         
          public function changeMap():void{   
                      
              trace(canvas.parent);         //Prints out SvgMap4
              removeChild(canvas);    
              if(canvas)trace("Canvas");   //Always prints out canvs
              else trace("No Canvas");          
         
              }       
          }
      }

       

      Could anyone please provide some clues on what I might have done wrong here? Why is it that I could not remove the child?

       

      Thanks for your help.

        • 1. Re: RemoveChild Errors
          Gregory Lafrance Level 6

          Calling removeChild() only removes it from the display list, it will still exist.

           

          You need to call removeChild() and then set canvas=null to get rid of it.

           

          Be sure you remove all references to it, usually with removeEventListener() calls if necessary.

           

          If this post answers your question or helps, please mark it as such.


          Greg Lafrance - Flex 2 and 3 ACE certified

          www.ChikaraDev.com

          Flex / AIR Development, Training, and Support Services

          • 2. Re: RemoveChild Errors
            alice_data Level 1

            Yes, and no. I could set it to null, but I could still see the initiated image, which is something I am trying to get rid at the point of the program before I can create new objects without having to create new layers.

             

            I think I might know why I cannot remove the child. However, again, I am not sure how I can fix this.

            This is the package that is called by the main application on Flex,

             

            package map
            {
                 import colorize.*;    
                 import com.zavoo.svg.*;
                
                 import flash.display.Sprite;
                 import flash.events.Event;
                 import flash.events.IOErrorEvent;
                 import flash.net.URLLoader;
                 import flash.net.URLRequest;
                
                 import mx.containers.Canvas;
                 import mx.core.UIComponent;

             

                public class SvgMap extends UIComponent {
                   
                    public var canvas:Sprite;
                    [Embed(source="USA_Counties_with_FIPS_and_names.svg")]
                    public var usaMap:Class;
                    public var paths:SvgPaths;             
                
                public function SvgMap():void {
                       
                            canvas = new usaMap();
                            canvas.width = 650;
                            canvas.height = 500;
                            addChild(canvas);              
                    }   
               
                public function changeMap():void{                    
                   
                    removeChild(canvas);   
                    if(canvas){
                            trace("I have access to a canvas : "+canvas);
                  if(canvas.parent) trace("canvas has a parent");
                            else trace("canvas does not have a parent");
                  if(canvas.stage) trace("canvas is on the display list");
                            else trace("canvas is not on the display list");
                    }  
                    else trace("There is no canvas");
                   
                    canvas = new Sprite();       
                    addChild(canvas);     
                  
                    }       
                }
            }

             

            This is my main app:


            <?xml version="1.0" encoding="utf-8"?>
            <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="100%"
                height="100%" creationComplete="addsvgMap()">
                <mx:Script>
                    <![CDATA[
                       import mx.events.SliderEvent;          
                       import mx.events.FlexEvent;        
                       import com.zavoo.svg.*;
                       import flash.display.Sprite;  
                       import colorize.*;   
                       import map.SvgMap;         
                       import flash.events.Event;
                       import flash.display.Graphics;   
                       import mx.events.SliderEvent;
                       import mx.core.IUIComponent;
               
                       public var thematicColorize:Thematiccolorize = new Thematiccolorize();
                       public var sliderCal:Slider = new Slider();    
                       public var svg:SvgMap = new SvgMap();         
                       public function addhorizontalbar():void{ vbox.addChild(sliderCal); //By this time, slider and horizontal bar has been created, no map             }        
                     
                      public function addsvgMap():void{
                     horizontal_bar.addChildAt(svg,0);    
               trace(horizontal_bar.numChildren);  //return 1, should it not be 2?                                                   
                 }           
                                            
                    ]]>
                </mx:Script>
               
                <mx:VBox id="vbox" x="20" y="10">           
                    <mx:Canvas id="horizontal_bar" width="350" height="520" creationComplete="addhorizontalbar()" />     
                </mx:VBox>         
                </mx:Application>

             

            So, I don't think under this circumstance, not even the "parent" is the same. Or, am I wrong?

             

            This is confusing.

            • 3. Re: RemoveChild Errors
              rickcr Level 1

              Greg Lafrance wrote:

               

              Calling removeChild() only removes it from the display list, it will still exist.

               

              You need to call removeChild() and then set canvas=null to get rid of it.

               

              Be sure you remove all references to it, usually with removeEventListener() calls if necessary.

               

              Not directly related to the OPs question, but related to the point above... Thanks for posting that since I wasn't aware of that, which brings up a question if this approach is overkill?....

               

              I have a case where views are dynamically created by the class name, and if the user clicks on a another report from a list, I want the old view components (all extend my base Prompt class) destroyed and any memory freed up.

               

              I'm currently doing it like this (each view prompt implements removeEventListeners and is responsible for clean up):

               

              for each (prompt in dataselectorContainer.getChildren()) {
                              prompt.removeEventListeners();
                              prompt = null;
              }

              dataselectorContainer.removeAllChildren();

               

              Is the above an ok approach (seems to work alright)? And I'm curious... how can you call remove on items that have been set to null? You'd think the reference would be gone, yet it's not?

              1 person found this helpful
              • 4. Re: RemoveChild Errors
                alice_data Level 1

                Yeah, that was my question too. You would think that you can set something to null, and then it would be gone, but it looks like its memory pertains in the system to somewhat.

                 

                Plus, when I run the app, it looks like that in the main app, it has one name for the objects, but again, when I see the number of children in a container, it is not necessary giving me the right number.I have to delete the object here, otherwise I can only create a new Sprite but not able to see it.

                 

                I wonder how can I delete the objects here now, since the instances are created with different names?

                • 5. Re: RemoveChild Errors
                  rickcr Level 1

                  alice_data wrote:

                  I wonder how can I delete the objects here now, since the instances are created with different names?

                   

                  If the things you want to delete are the only things added to the parent then it's easy you just do something similar to what I was doing.. iterate over parent children, remove event listeners, set to null, then remove all the chilren.

                   

                  If the objects are being added and removed from a container that also holds things  you don't want to remove, I'd just keep track of the object as a reference  (var currentObject ) when you go to add it, then you can just remove it by the reference. If adding multiple just store them in a collection.

                  • 6. Re: RemoveChild Errors
                    alice_data Level 1

                    Hi,

                     

                      I took a look at the advice you two had suggested, and looks like that function you two suggested was not entirely necessary.

                     

                      Since I expected this to only be "triggered" when a user moves the slider, I moved the function of what I intended to do from the beginning to the class where a slider is. This actually took me some variables passing around between main and child classes. However, it looks like the "child" is called as I had expected. Strangely, I still could not delete the child directly, since I got error #2025 with the supplied DisplayObject must be a child of the caller. I solved the problem eventually, by deleting this child from its parent:

                     

                    BTW, the code is in the following:


                    private var childname:DisplayObject;   
                    public function changeData(e:Ev
                    ent):void{
                                  if(horizontal_bar) trace("Test Only " + horizontal_bar.getChildAt(0)); 
                                 
                                  childname = horizontal_bar.getChildAt(0);
                                  trace("Parent " + childname.parent);
                                childname.parent.removeChild(childname);
                                if(childname){
                                    trace("I have access to a canvas : "+ childname);
                                if(childname.parent) trace("canvas has a parent");
                                    else trace("canvas does not have a parent");
                                if(childname.stage) trace("canvas is on the display list");
                                   else trace("canvas is not on the display list");
                            }  
                            else trace("There is no canvas");        
                              }       

                     

                    The output:

                     

                    Test Only main9.vbox.horizontal_bar.SvgMap7
                    Parent main9.vbox.horizontal_bar
                    I have access to a canvas : SvgMap7
                    canvas does not have a parent
                    canvas is not on the display list

                     

                    You guessed it, the image that has been driven me nuts all this time has left the screen.

                     

                    Thanks!