jaku
jaku

Reputation: 36

access variable between dynamic created Objects from library

Welcome,

I was created simple FLA project (AIR 3.6 for iOS - sources):

var k1:kloc1 = new kloc1();
var k2:kloc2 = new kloc2();

k1.x = 0;
k1.y = 0;
k2.x = 150;
k2.y = 150;

addChild(k1);
addChild(k2); 
trace("k2 name main timeline: " + k2.name);  
trace("k2 demo_tekst before: " +  MovieClip(root).k2.demo_tekst);  
k2.demo_tekst = 'podmieniony tekst';  
trace("k2 demo_tekst after: " +  MovieClip(root).k2.demo_tekst);  

kloc2 is in library, inherit from MovieClip and contains only demo_tekst varabile:

var demo_tekst:String = "oryginalny tekst";

and kloc1 is also in library, inherit from MovieClip and contains only listener, and trace instruction:

addEventListener(MouseEvent.CLICK, onClick);
function onClick(e:MouseEvent):void {
    trace("k2 name from k1 obj: " + MovieClip(root).k2.name);
    trace(MovieClip(root).k2.demo_tekst);
}

When I test above code, by clicking k1, the result on console is:

k2 name main timeline: instance3
k2 demo_tekst before: null
k2 demo_tekst after: podmieniony tekst
k2 name from k1 obj: instance3
oryginalny tekst

Final result is "oryginalny tekst", not "podmieniony tekst", as I expect. Also after creatin k2 object, by new(), demo_tekst is null (?!). I was check it in debug mode, and k2 has the same instance while it was created, and during tracing the result. Object name is equal in both places. Can someone explain me what is going on?

Upvotes: 1

Views: 231

Answers (1)

Atriace
Atriace

Reputation: 2558

k2 name main timeline: instance3

This is expected for dynamically created objects. You need to give the instance a name when creating it, or it will generate one for you. Since this was the 3rd object on stage, it becomes "instance3".

Solution:

var k2:kloc2 = new kloc2();
k2.name = "myK2";
trace("My k2.name = " + k2.name);  // My k2.name = myK2

k2 demo_tekst before: null

Writing MovieClip(root) simply datatypes the root as a MovieClip object (which it already is). You can simplify this by writing:

root.k2.demo_tekst

However, while you may have a property called "k2" on your root object (a.k.a. MainTimeline), you don't have DisplayList object by that name. The DisplayList and the properties on an object are two distinctly separate things. In your case, there is a property on root called "k2" which points to your MovieClip, but the name property was left blank, so its automatic name is "instance3".

The reason for this seemingly convenient pointer is because by default Flash IDE has "Automatically declare stage instances" enabled. Seeing that you've created library objects, a property pointing to your MovieClip has automatically been created in root.

This isn't an option if you've manually created your objects at runtime. Normally, you would need to manually declare these to use dot.notation syntax.

k2.name = "k2";
root.addChild(k2);
root[k2.name] = k2;

Conversely, you could use root.getChildByName("k2") and forego the pointer creation in the root object. In many cases, this would be the correct way of doing it, although a bit more cumbersome.


k2 demo_tekst after: podmieniony tekst

If you come from Flash IDE and AS2, you're probably used to creating ActionScript directly on the timeline of each subordinate object. Don't do that in AS3.

It is my belief that the demo_tekst variable is not initialized because the MovieClip is not played, ergo there is no k2.demo_tekst until you've dynamically created it outside of your MovieClip object by writing k2.demo_tekst = 'podmieniony tekst'; Because MovieClips are dynamic, you can spawn these variables without conflict (not so with non-dynamic objects like Sprite or Shape).

Consider creating your MovieClips completely dynamically as follows:

var k1:MovieClip = new MovieClip();
k1.name = "kloc1";
k1.demo_text = "replacement text";
addChild(k1);
trace(k1.name + ".demo_text = " + k1.demo_text);
// outputs:  kloc1.demo_text = replacement text

k2 name from k1 obj: instance3

oryginalny tekst

The first line is expected (since you never named the k2 object), but this is where order of operation becomes interesting in timeline code (highly recommend not doing it). After the movieclip is parented to the MainTimeline, the code inside the timeline of your child MovieClip is finally run, which then overwrites the internal property demo_tekst.

I hope this clarifies things. Again, I highly implore you to write all your code in one document if you want to keep things simple. You can do this on the first frame, or write it externally and include it in your timeline.

If you're ready to go beyond the basics, consider creating your own class objects and importing them. This gives you the power of creating complex properties and functions on your custom objects (which appears to be your original intent).

Upvotes: 1

Related Questions