views:

9431

answers:

5

So I successfully added a movie clip from the library using addChild(), but now I want to access some movieclips that were in that dynamically added movieclip.

I've used standard dot notation and also getChildByName passing it the instance names.

What am I missing here?

---- EDITED ----

I tried the suggestion of looping through and can access them by index, but seems like not as intuitive of a way to do this... below are the two examples of what I had previously tried and they all come back as "1119: Access of possibly undefined property nameText through a reference with static type flash.display:DisplayObject." or "1061: Call to a possibly undefined method getChildByName through a reference with static type flash.display:DisplayObject."

example of dot notation:

 //  build circlular display
function buildCircle() {
    trace("buildCircle()");
    if (viewByState == "assignment") {

     var competencyContainer:MovieClip = new MovieClip();
     competencyContainer.name = "competencyContainer";
     this.addChild(competencyContainer);

     var angleSegment:Number = 360 / competenciesArray.length;
     var angleSum:Number = 360 - angleSegment / 2;

     for (var i:Number = 0; i < competenciesArray.length; i++) {

      var competencyInstance:competencyCircle = new competencyCircle();
      competencyInstance.name = "competency" + i;
      competencyContainer.addChild(competencyInstance);


      competencyContainer.getChildByName("competency" + i).x = circleCenter.x - (Math.sin(angleSum * (Math.PI / 180)) * (circleSize / 2));
      competencyContainer.getChildByName("competency" + i).y = circleCenter.y - (Math.sin((90 - angleSum) * (Math.PI / 180)) * (circleSize / 2));


      competencyContainer.getChildByName("competency" + i).nameText.wordWrap = true;
      competencyContainer.getChildByName("competency" + i).nameText.embedFonts = true;
      competencyContainer.getChildByName("competency" + i).nameText.htmlText = "COMPETENCY:<br />" + competenciesArray[i].name;

      competencyContainer.getChildByName("competency" + i).nameText.setTextFormat(tfTitle, 0, competencyContainer.getChildByName("competency" + i).nameText.text.length - competenciesArray[i].name.length);

      competencyContainer.getChildByName("competency" + i).nameText.setTextFormat(tfName, competencyContainer.getChildByName("competency" + i).nameText.text.length - competenciesArray[i].name.length, competencyContainer.getChildByName("competency" + i).nameText.text.length);

      competencyContainer.getChildByName("competency" + i).nameText.autoSize = TextFieldAutoSize.CENTER;

      competencyContainer.getChildByName("competency" + i).nameText.y = -(competencyContainer.getChildByName("competency" + i).nameText.height / 2);

      competencyContainer.getChildByName("competency" + i).filters = [circleDefaultDropShadow];
      competencyContainer.getChildByName("competency" + i).selectedIndicator.visible = false;

      competencyContainer.getChildByName("competency" + i).hit.buttonMode = true;
      competencyContainer.getChildByName("competency" + i).hit.mouseEnabled = true;
      competencyContainer.getChildByName("competency" + i).hit.tabEnabled = true;
      competencyContainer.getChildByName("competency" + i).hit.mouseChildren = true;

      competencyContainer.getChildByName("competency" + i).hit.addEventListener(MouseEvent.MOUSE_OVER, function(e:MouseEvent) {
                         e.target.parent.filters = [circleHoverDropShadow];
                         });

      competencyContainer.getChildByName("competency" + i).hit.addEventListener(MouseEvent.MOUSE_OUT, function(e:MouseEvent) {
                         e.target.parent.filters = [circleDefaultDropShadow];
                         });

      competencyContainer.getChildByName("competency" + i).hit.addEventListener(MouseEvent.CLICK, function(e:MouseEvent) {
                         e.target.parent.filters = [circleDefaultDropShadow];
                         e.target.parent.selectedIndicator.visible = true;
                         });

      angleSum -= angleSegment;
      trace("end");
      trace(i);
      trace("\n\n\n");
     }
    } else if (viewByState == "competency") {



    } else {

    }
}
buildCircle();

and example using .getChildByName():

    //  build circlular display
  function buildCircle() {
    trace("buildCircle()");
    if (viewByState == "assignment") {

        var competencyContainer:MovieClip = new MovieClip();
        competencyContainer.name = "competencyContainer";
        this.addChild(competencyContainer);

        var angleSegment:Number = 360 / competenciesArray.length;
        var angleSum:Number = 360 - angleSegment / 2;

        for (var i:Number = 0; i < competenciesArray.length; i++) {

                var competencyInstance:competencyCircle = new competencyCircle();
                competencyInstance.name = "competency" + i;
                competencyContainer.addChild(competencyInstance);


                competencyContainer.getChildByName("competency" + i).x = circleCenter.x - (Math.sin(angleSum * (Math.PI / 180)) * (circleSize / 2));
                competencyContainer.getChildByName("competency" + i).y = circleCenter.y - (Math.sin((90 - angleSum) * (Math.PI / 180)) * (circleSize / 2));


                competencyContainer.getChildByName("competency" + i).getChildByName("nameText").wordWrap = true;
                competencyContainer.getChildByName("competency" + i).getChildByName("nameText").embedFonts = true;
                competencyContainer.getChildByName("competency" + i).getChildByName("nameText").htmlText = "COMPETENCY:<br />" + competenciesArray[i].name;

                competencyContainer.getChildByName("competency" + i).getChildByName("nameText").setTextFormat(tfTitle, 0, competencyContainer.getChildByName("competency" + i).getChildByName("nameText").text.length - competenciesArray[i].name.length);

                competencyContainer.getChildByName("competency" + i).getChildByName("nameText").setTextFormat(tfName, competencyContainer.getChildByName("competency" + i).getChildByName("nameText").text.length - competenciesArray[i].name.length, competencyContainer.getChildByName("competency" + i).getChildByName("nameText").text.length);

                competencyContainer.getChildByName("competency" + i).getChildByName("nameText").autoSize = TextFieldAutoSize.CENTER;

                competencyContainer.getChildByName("competency" + i).getChildByName("nameText").y = -(competencyContainer.getChildByName("competency" + i).getChildByName("nameText").height / 2);

                competencyContainer.getChildByName("competency" + i).filters = [circleDefaultDropShadow];
                competencyContainer.getChildByName("competency" + i).getChildByName("selectedIndicator").visible = false;

                competencyContainer.getChildByName("competency" + i).getChildByName("hit").buttonMode = true;
                competencyContainer.getChildByName("competency" + i).getChildByName("hit").mouseEnabled = true;
                competencyContainer.getChildByName("competency" + i).getChildByName("hit").tabEnabled = true;
                competencyContainer.getChildByName("competency" + i).getChildByName("hit").mouseChildren = true;

                competencyContainer.getChildByName("competency" + i).getChildByName("hit").addEventListener(MouseEvent.MOUSE_OVER, function(e:MouseEvent) {
                                                                                                                                                                 e.target.parent.filters = [circleHoverDropShadow];
                                                                                                                                                                 });

                competencyContainer.getChildByName("competency" + i).getChildByName("hit").addEventListener(MouseEvent.MOUSE_OUT, function(e:MouseEvent) {
                                                                                                                                                                 e.target.parent.filters = [circleDefaultDropShadow];
                                                                                                                                                                 });

                competencyContainer.getChildByName("competency" + i).getChildByName("hit").addEventListener(MouseEvent.CLICK, function(e:MouseEvent) {
                                                                                                                                                                 e.target.parent.filters = [circleDefaultDropShadow];
                                                                                                                                                                 e.target.parent.getChildByName("selectedIndicator").visible = true;
                                                                                                                                                                 });

                angleSum -= angleSegment;
                trace("end");
                trace(i);
                trace("\n\n\n");
        }
    } else if (viewByState == "competency") {



    } else {

    }
}
buildCircle();
+1  A: 

In AS3, dot notation doesn't work the way it used to in AS2. You can use it if and only if you have explicitly declared the child's name as a variable of parent object. getChildByName is also not reliable as there is no rule that says two siblings can't have same name. Use getChildAt to loop through all the children. Try something like:

//assuming newMC as the added movie clip
var num:Number = newMC.numChildren;
for(var i:Number = 0; i < num; i++)
{
  var child:DisplayObject = newMC.getChildAt(i);
  trace(child.name);
}
Amarghosh
Uhh what? Of course dot notation works in AS3, you just have to utilize instance names. If you know what you're trying to access then you shouldn't be looping through children.
Jasconius
Dot notation in AS2 works in a totally different way. A parent can access its child by its name like: parentMC.childMC._x = 30; childMC need not be an instance variable of parentMC class for this line to work in AS2. childMC is just the name of the parent.
Amarghosh
It doesn't have to be that way in AS3 either. MovieClips are still dynamic classes in AS3 and you can access them based off of stage names. Your point about duplicate state names is valid, but at worst you'll get a compiler warning. myMC.someStageInstance is still completely valid in AS3. I use it every day.
Jasconius
myMC.someStageInstance to work in AS3, you should have called myMC.someStageInstance = something; sometime earlier. In AS2 if you call myMC.attachMovieClip with someStageInstance, you can call myMC.someStageInstance to get it.
Amarghosh
To OP: competencyContainer.getChildByName("competency" + i).x can be replaced with competencyInstance.x and that's how you do it in AS3. Treat child movies as separate movieclips rather than referring them thru parents. Store them in an array and loop thru them if you want.
Amarghosh
getChildByName returns a DisplayObject. You have to cast it to competencyCircle to access the nameText property. It is: competencyCircle( competencyContainer.getChildByName(childName)).nameText;
Amarghosh
competencyContainer.getChildByName("competency" + i).getChildByName("nameText").wordWrap = true; gives the 1061 error because getChildByName returns a DisplayObject and getChildByName is a method of DisplayObjectContainer class. You have to cast.
Amarghosh
If nameText is a property of competencyCircle class, you can access it using var cc:competencyCircle = competencyCircle( competencyContainer.getChildByName("competency" + i)); and then call cc.nameText;
Amarghosh
Oh, you're talking about child clips that were dynamically added. You misread his question. He's already dynamically added a clip from the library, now he is trying to access children of the clip he added, presumably these children were already on the stage in the library. Maybe the OP should better word his question, it is a little confusing.
Jasconius
A: 

You need to have a reference to the movieclip that was dynamically added. Then you can access a particular child movieclip if it has an instance name.

So if you have MovieClip with instance name 'a' and inside you have a MovieClip with instance name 'b' then you can simply reference it as a.b. But as Amarghosh pointed out flash will let you have multiple movieclips with the same instance names and if thats the case only one of the movieclips will be accessed.

Allan
A: 

Ok, I have read through your code a few times and would like to point out the following.

The below is a snippet of your code:

 var competencyInstance:competencyCircle = new competencyCircle();
 competencyInstance.name = "competency" + i;
 competencyContainer.addChild(competencyInstance);

 competencyContainer.getChildByName("competency" + i).x = circleCenter.x - (Math.sin(angleSum * (Math.PI / 180)) * (circleSize / 2));
 competencyContainer.getChildByName("competency" + i).y = circleCenter.y - (Math.sin((90 - angleSum) * (Math.PI / 180)) * (circleSize / 2));

It looks to me as tho your just setting attributes of competencyInstance, but for some reason your doing it through the parent. I would assume that you are an AS2 developer learning AS3, because this is an AS2 method. You have a reference to the object already and do not need to access the parent.

The following is how your code should look.

 var competencyInstance:competencyCircle = new competencyCircle();
 competencyInstance.name = "competency" + i;

 competencyInstance.x = circleCenter.x - (Math.sin(angleSum * (Math.PI / 180)) * (circleSize / 2));
 competencyInstance.y = circleCenter.y - (Math.sin((90 - angleSum) * (Math.PI / 180)) * (circleSize / 2));
 competencyContainer.addChild(competencyInstance);

The x and y are always relative to the parent.

The best way to figure these things out, is to iterate through the parent/container tracing out the name of each object, you may find that you forgot that you nested things one deeper, etc.

The as3 display list is a great thing, because you can access objects through their direct reference, instead of the long dot syntax referencing through the parent. The only time you need to access things through the parent as your doing, is when you do not have a reference. You created a local variable competencyInstance which is only access-able while buildCircle() is exectuing, once buildCircle() is finished running, the life of all local variables created within it ends. That all being said, when you don't have a reference, you will have to use the for loop iterate through parent method accessing each child.There is alot more I could say about the display list and its wonders, but I want to stick to what pertains.

Brian Hodge hodgedev.com

Brian Hodge
A: 

I was able to easily access the child objects within a dynamically loaded library movieClip. I actually made a manual loop that creates buttons based on the number of elements in an XML document. A tween function is called and once the animation completes, a new button instance is created and positioned according to my x value calculation. What I made here is a Flash navigation for a website. I wanted to switch the "select" movieclip on if the user clicks a button and turn it off if the user selects a different button.

You were on the right track and I essentially used what you were doing with the getChildByName method. With a for loop, I was able to access all of the dynamically loaded button's children by referencing the names I gave them when they were created (in this case "btn_" plus the value of the variable "i.") i.e. "btn_0, btn_1, btn_2" etc. The buttons were then added to the btnGroup movie clip. So in essence, all I needed to do was reference the child elements of btnGroup using getChildByName("movie clip name") followed by the name of the object you want to acces from the child in brackets[""] in the form of a string. View my "Mouse function" example below to get right to the answer

function btnMaker():void
{
btnGroup.x = 170;
if(btnCount < clubXML.btn_group..length())
{
btnCount++;
b = new btn();
spacer = b.width-27;
b.x = (btnCount-1)
spacer;
b.y = 25;
b.name = "btn_"+(btnCount-1);//Name the dynamicly loaded movie clip
b.buttonMode = true;
b.mouseChildren = false;
b.btn_txt.text = clubXML.btn_group.btn[btnCount-1];
b.addEventListener(MouseEvent.CLICK, mouseFunctions);
b.addEventListener(MouseEvent.MOUSE_OVER, mouseFunctions);
b.addEventListener(MouseEvent.MOUSE_OUT, mouseFunctions);
b.grid_mc.stop();
b.grid_mc.visible = false;
b.select.visible = false;
btnGroup.addChild(b);
btnGroup.getChildByName("btn_0")["select"].visible = true;
tweenIn();
}
if(btnCount == clubXML.btn_group.*.length())
{
//btnTimer.stop();
xTween.removeEventListener(TweenEvent.MOTION_FINISH, animFinish);
}
}

function mouseFunctions(e:MouseEvent):void

var btnName = e.target.name.substring(4, 5);

switch(e.type)
{
case("mouseOver"):
bounceIn = new Tween(e.target, "scaleY", Bounce.easeOut, 1.5, 1, 10, false);
e.target.gotoAndPlay(2);
e.target.getChildByName("grid_mc").visible = true;
//trace(e.target.getChildByName("grid_mc").totalFrames());
e.target.getChildByName("grid_mc").play();
break;

case("mouseOut"):
e.target.gotoAndPlay(12);
e.target.getChildByName("grid_mc").stop();
e.target.getChildByName("grid_mc").visible = false;
break;

case("click"):
trace("Button Name: "+btnName);

currentSelection = e.target.name;

for(var i:int = 0; i < btnGroup.numChildren-1; i++)
{
btnGroup.getChildByName("btn_"+i)["select"].visible = false;
}

notIt != currentSelection;

if(currentSelection != notIt)
{
e.target.getChildByName("select").visible = true;
}
break;
}
}

I hope this helps you.

Peace

mastermalone
A: 

What about using this when create the clips:

...
competencyInstance.name = "competency" + i;  
competencyContainer.addChild (competencyInstance);          
// this is the additional line, cecessary for accesing later by name
competencyContainer["clipFichaEjemplo2"] = competencyInstance;
...

And this to access them later:

...
var M:MovieClip = clipMapa["competency" + i];
...

it worked for me in a similar flash project where i have the problem using addChild dynamically.

ihih: I hope it helps :)

Tomas