TheD2000
TheD2000

Reputation: 233

AS3 - Get the child name from within itself (a bit like this.name):

I've added a MovieClip from the Library to the stage using the addChild() function. The child name has come from an array. I now need to place a piece of code within the MovieClip I added to look at itself and return what it's 'child' name is so that it can run a whole bunch of if statements etc. to configure itself from the inside. For example, it can look back at the informationWindows and pull through data based on it's own informationName this.name will not work because I am not using the instance name as reference.

//
//The array within simulator_constants...
static public var informationWindows:Array = new Array(
    {_informationName:"testPopUp", _popupType:"1", _x:"0", _y:"0", _title:"Example Pop-Up Window",  _subtitle:"Something Happened", _media:"image", _text:"window text here"},      
    {_informationName:"anotherTestPopUp", _popupType:"2", _x:"100", _y:"100", _title:"Example Pop-Up Window",  _subtitle:"Something Happened", _media:"image", _text:"window text here"},
    {_informationName:"oneLastPopUp", _popupType:"1", _x:"200", _y:"200", _title:"Example Pop-Up Window",  _subtitle:"Something Happened", _media:"image", _text:"window text here"}
);
//  ------------------------------------------ //
//  ------------------------------------------ //
//  ------------------------------------------ //
//  The code that adds the Info_win Movieclips and their Class from the Library to the main stage...
var infoWinArray:Array = [];

// Count the number of windows that will be called upon...
var informationWindowCount:Number = simulator_constants.informationWindows.length; 

// Add the information windows to the Stage and dynamically give them names that we require...
for (var i:Number=1; i<=informationWindowCount;i++){
    infoWinArray[i-1] = new Info_win();
    infoWinArray[i-1].name = simulator_constants.informationWindows[i-1]._informationName;
    addChild(infoWinArray[i-1]);                
}

This is the other half of my issue, you guys helped solve the initial part of it. Unfortunately, I can't find a way to then give the childs instance name the same as it's child's name. If I could, then I would just run this.name from within the MovieClip in question.

Upvotes: 1

Views: 270

Answers (1)

null
null

Reputation: 5255

Receive the information instead of getting it yourself

return what it's 'child' name is so that it can run a whole bunch of if statements etc. to configure itself from the inside.

This is overcomplicated and not a good idea in general. As it looks now, you made this array static in order to access its elements "from the inside" of the newly created windows. As DodgerThud also suggested in the comments: instead of giving the object a name and send it on a scavenger hunt in order to find the necessary information, simply give it the information directly.

I applied some modifications to the following code:

  1. Info_win changed to InfoWindow
  2. introduced a local variable (always preferable)
  3. changed for loop counting instead of subtracting 1 all the time

code:

var windows:Array = [];

for(var i:uint = 0; i < informationWindowCount; ++i)
{
    var window:InfoWindow = new InfoWindow(informationWindows[i]);
    windows.push(window);
    addChild(window);
}

As you can see, the whole object (the array element) is passed to the constructor, which allows the constructor to "configure itself from the inside" without grabbing the information from somewhere.

Passing an object to a constructor as you do in order to define how it is set up is usually called a configuration object.

Create a class for your configuration objects

Generic objects are quick and easy but also fail as quickly and as easily. If you create a class for them, you can

  • check the values to be valid
  • set default values
  • create constants for types
  • add more functionality (like serialisation/deserialisation for example)

Such a class could look something like this:

package
{
    public class WindowConfiguration
    {
        public static const TYPE_1:uint = 1; //your types should have more descriptive names
        public static const TYPE_2:uint = 2;
        private static const TYPES:Array = [TYPE_1, TYPE_2];

        public static const IMAGE:String = "image";

        private var name:String;
        private var type:uint;
        private var x:Number;
        private var y:Number;
        private var title:String;
        private var subtitle:String;
        private var media:String;
        private var text:String;

        public function WindowConfiguration(name:String = "testPopUp", 
                                            type:uint = TYPE_1, 
                                            x:Number = 0, 
                                            y:Number = 0, 
                                            title:String = "Pop-Up Window",  
                                            subtitle:String = "", 
                                            media:String = IMAGE, 
                                            text:String = "")
        {
            this.name = name;

            if(TYPES.indexOf(type) == -1)
                throw new ArgumentError("invalid type: " + type);
            this.type = type;

            // etc
        }

        public function get name():String
        {
            return name;
        }

        public function get type():uint
        {
            return type;
        }

        // etc
    }
}

With this in place, your array of configuration objects changes to something like this:

var windowConfigurations:Array = [
    new WindowConfiguration("testPopUp", WindowConfiguration.TYPE_1, 0, 0, "Example Pop-Up Window", "Something Happened", WindowConfiguration.IMAGE, "window text here"),      
    new WindowConfiguration("anotherTestPopUp", WindowConfiguration.TYPE_2, 100, 100, "Example Pop-Up Window", "Something Happened", WindowConfiguration.IMAGE, "window text here"),
    new WindowConfiguration("oneLastPopUp", WindowConfiguration.TYPE_1, 200, 200, "Example Pop-Up Window", "Something Happened", WindowConfiguration.IMAGE, "window text here")
];

The whole code could look like this. Note that I changed some variable names.

var windowConfigurations:Array = [
    new WindowConfiguration("testPopUp", WindowConfiguration.TYPE_1, 0, 0, "Example Pop-Up Window", "Something Happened", WindowConfiguration.IMAGE, "window text here"),      
    new WindowConfiguration("anotherTestPopUp", WindowConfiguration.TYPE_2, 100, 100, "Example Pop-Up Window", "Something Happened", WindowConfiguration.IMAGE, "window text here"),
    new WindowConfiguration("oneLastPopUp", WindowConfiguration.TYPE_1, 200, 200, "Example Pop-Up Window", "Something Happened", WindowConfiguration.IMAGE, "window text here")
];

var windows:Array = [];

for(var i:uint = 0; i < windowConfigurations.length; ++i)
{
    var window:InfoWindow = new InfoWindow(windowConfigurations[i]);
    windows.push(window);
    addChild(window);
}

Additional thoughts

  1. As the code stands, it always requires a WindowConfiguration object to be instantiated. This can be cumbersome. To avoid this:
    1. create a default constructor in the InfoWindow class, that creates a default InfoWindow object, this constructor can be called without a WindowConfiguration and is thus more versatile
    2. create a `public static function fromConfiguration(configuration:WindowConfiguration):InfoWindow`` which acts like an additional constructor: it calls the default constructor, sets the parameters according to the configuration and returns the resulting object
  2. This is more a comment than part of this answer. Consider refactoring your code. Your window is doing a lot. Is it really necessary that the window knows that it is displaying an image? Maybe it's better to let the window class just provide the functionality of a window (drag it around, be on top of another window, be closed, minimized etc.) and let it display any kind of Content, maybe even any DisplayObject. If that's really a good idea depends on what the window is supposed to do.

Upvotes: 2

Related Questions