Understanding root and the Document Class in AS3 ·
11 December 2007, 12:44
Hopefully, we all know the _root object is gone in AS3. While use of _root was generally frowned upon in the Actionscript dev community, it had its uses. It was a quick and easy way to reference your project's main timeline. Moving into AS3, we let go of _root and embrace the concept of a Document Class.
The purpose of the Document Class in AS3 is to extend your project's main timeline (just a MovieClip instance) with a custom MovieClip subclass. While a similar effect was achievable in AS2, it required using a work-around. It's nice to be able to assign your project a 'main' class right from the properties panel in Flash CS3.
You may be thinking that comparing the 'AS2 _root' to the 'AS3 Document Class' is like comparing apples to oranges, and you would be right. The _root object in AS2 was a reference to the project's main timeline, whereas the Document Class is not a reference at all; it is a subclass of the MovieClip object that serves as the Actionscript's entry point into your project.
Sooooo, why does it make sense to talk about them together...? In order to understand the concept of root (not _root!!!) in AS3 you need to understand the concept of the Document Class.
In AS3 every DisplayObject (instances and subclasses of TextField, Sprite, MovieClip, etc...) contains a root property that is a reference to the Document Class once the DisplayObject is added to the display list. It is important to realize that the DisplayObject's root property will be null if it is not on the display list.
I have created a really bare bones example of how to interact with the root property of DisplayObjects in AS3. I have a Main class (the Document Class of my FLA) and a Child class (a subclass of Sprite) to be added to the display list.
My Child class has a single method called traceRoot which will trace out the current value of the Child's root property and then attempt to call a method on the Main class.
The Child class:
package
{
import flash.display.*;
public
{
public
{
trace('--- a new Child has been instantiated ---')
}
public
{
trace('findRoot from ' + this.root)
trace('attempting to call the getFoo() method on this child\'s root....');
try
{
// root refers to the Document Class (the class assigned to the stage), but it has
// to be casted as the type of the Document Class if you want to be able to access its members
trace('Success! getFoo(): ' + Main(root).getFoo());
trace('root: ' + root)
}
catch(err:Error)
{
trace('Failed! Could not access the root to call the getFoo function... please add this child instance to the display list')
}
}
}
}
I am using a try/catch statement in the traceRoot function, because if the Child is not on the display list and I attempt to access the root property, the FlashPlayer will throw a runtime error... accessing a member of a null property is a no-no.
Another important thing to notice: once my Child is on the stage, meaing the root property is not null, I still need to Cast the root reference to the type of my Document Class before I can access its members. Even though the Flash Player knows that the root property is of the type Document Class, it still needs to be formally casted, since the root property is always expected to be a Sprite.
Hope this helps clear up some confusion regarding the Document Class in AS3 and the new root property.
Here are the source files for my simple demo if you want to get a hands on look at these concepts in action
☆ Jonathan Greene
comments:
Commenting is closed for this article.
Once again, thanks a bunch! :-)
— Johan Nyberg · Dec 12, 06:00 AM · #
So, when would you suggest using the static array in the GlobalVarContainer class (another brilliant article, btw :-), and when should one access public variables/methods in the Document Class through the root property?
— Johan Nyberg · Dec 12, 06:16 AM · #
I shy away from making any variable public :). If you need to be able to adjust variables on an object, you should use a public setter method on that object. It is always better to have an object manage its own internal properties.
To be honest, I don’t use the root too much in AS3, but its good to understand what it is. If I were to find myself using root, it would be to trigger a method on the Document Class.
An alternative (and preferred) way of calling methods on the Document Class would be to bubble events up the display list and catch them at the top-level (your Document class). I still struggle a bit with executing this properly, but once I get it figured out, it’ll be an new article for sure!
— Jon · Dec 12, 09:27 AM · #
What I’m referring to is not so much public variables – I don’t like them either – but rather references to MovieClips on the stage. The only way to access them is either via the root property or by storing the references in a GlobalVarContainer-type-of-class.
— Johan Nyberg · Dec 12, 10:28 AM · #
yeah, as far as I know if you just want to reference any clip directly on your stage, from a somewhere nested down the Display List, root is the quick and dirty way… and really the only way to do it without using events to trigger functions in your Document Class..
Have you worked at all with Events in AS3?
— Jon · Dec 13, 12:41 PM · #
I’m presently migrating from AS2 to AS3, so yes, I’ve started to come to grips with the new event model. But I’m still a bit foggy about all that bubbling stuff… :-)
I just find that I sometimes want to be able to reference clips in my movie. For example, I have a clip that holds the frame (yes, an actual frame as in picture frame) of the movie, and it sets the boundaries.
Referencing it is a convenient way of founding the visible bounds of the movie.
I shouldn’t have to trigger an event to do that, should I?
— Johan Nyberg · Dec 13, 03:02 PM · #
no… you shouldn't have to. I would have to see your project structure to be able to offer more specific advice. if you’d like, i can take a quick look at your project and see if i can help.
— Jonathan Greene · Dec 14, 12:48 PM · #
Dear Jonathan Greene, great stuff here, I’m new to as3 as the rest of the world. i can’t get a solution to the stage proprties. do you have an example for that ? I will appreciate if you post one.
— Dubi Sharon · Dec 15, 01:14 PM · #
Hey Dubi,
Have a look at the Stage documentation in the AS3 reference manual (http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/) to see the stage related properties and methods you have available to you.
As far as acessing the stage object and its properties/methods, you can use the inherent ‘stage’ property on any Display Object. Just like the ‘root’ property, the ‘stage’ property will be null unless the the Display Object is added to the display list.
I updated the source files on this post to trace out some stage properties.
Cheers,
-Jon
— Jonathan Greene · Dec 16, 10:51 PM · #
Hi again Jon. Thanks a bunch for your willingness in taking a look at my project! I am presently working towards a deadline with another project, but can I get back to you at the beginning of next year? I can’t seem to find your email anywhere on the site, could you please mail it to me?
Thanks again for taking your time.
— Johan Nyberg · Dec 19, 08:45 AM · #
I won’t be doing any major QA :), but I would be happy to have a look at the project and see what might be messing you up. I sent ya my email address… good luck with your deadlines!
— Jon · Dec 19, 09:47 AM · #
Thanks for the info. I was trying to reference a method of the document class from a child object using something like you’re explaining, but was missing the cast – DocumentClassName(this.root);
— peaceoutside.org · Aug 26, 12:22 PM · #
Thanks so much for making the simple example available. After going round in circles for a while, you solved my issue within a couple of minutes!
James
— Stag do · Dec 13, 08:05 AM · #
Thanks a lot! Was of great help!
— Muddy · Jun 29, 03:55 AM · #
turning off comments on this thread temporarily due to crazy spam attack.
— Jonathan · Sep 5, 01:13 PM · #