How to call a method in document class, from loader content movie AS3

Hi im trying to make as small app but I'm having trouble accessing functions in the document class from the sibling movie that has been externally loaded.

I'm sure its that I'm just going about this totally the wrong way, I'm fairly new to AS3 and usually use AS2.

See the code and comments below,
// In the external child mc im Trying to call
 
stage.lift();
 
// lift(); being a public function of the document class.  However I get the following compile error
// 1061: Call to a possibly undefined method lift through a reference with static type flash.display:Stage.
 
 
// if I cast the stage to a MovieClip, or StageManager (the doc Class extends MovieClip) the compile error goes away but I get a runtime error
// TypeError: Error #1034: Type Coercion failed: cannot convert flash.display::Stage@2de94b51 to flash.display.MovieClip.
 
 
//So I am stuck any suggestions would be welcomed.

Open in new window

LVL 6
gxp071Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

blue-genieCommented:
howdy.
this is how I do it. And so far no one has been able to tell me if its the right way or not.

assume your document class is called Box

Box(root).lift();

0
gxp071Author Commented:
Hi thanks for the comment,

My document class is called StageManager, and ive tried

StageManager(root).lift();

but i get the following runtime error,

TypeError: Error #1034: Type Coercion failed: cannot convert flash.display::MovieClip@270cac41 to StageManager.
0
rascalpantsCommented:
A better way to do this is to have both classes setup to be able to dispatch and listen for custom events.

here is an example of a custom event tutorial...

http://flexcomps.wordpress.com/2008/04/29/dispatching-custom-events-in-as3-with-data-or-object/


but basically, this allows your application to be built in a way that it doesn't need to know anything about the structure of a class, it just sends off a message, and who ever wants to listen to that message, will, and respond appropriately.


rp
0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

blue-genieCommented:
thanks for that rp.
But i'm curious why my little hack doesn't work.
your stageManager class extends Movieclip right?
0
gxp071Author Commented:
Afraid not,

and yes StageManager does extend MovieClip.

And I agree with you that it should work but for some unknown reason it does not.  If I cast it as a MovieClip it doesn't get the 1034 Error but instead cant find the function/ not defined which makes sense as MovieClip doesn't have the functions defined in StageManager...

Will try out the custom event tutorial but I have a feeling that there must be something else in my code thats angering the Flash IDE compiler.
0
ruijietanCommented:
The reason it doesn't work is because the document class is NOT the 'stage', and you're trying to call functions on 'stage'.

This is how the layout works.

When you start the Flash Player, your main class is not loaded as a stage instance, but instead at one level lower.

Stage -> Your App's Document Class -> Loader -> content property of Loader.

So technically by accessing stage.lift(); you are trying to call a non-existent function on Stage.

Also in AS3 the _lockroot property is always enforced, so by calling root.lift(); you will be instead calling the lift(); function in the loaded movie, not your main movie, which is not your intended purpose.

You should try rascalpants' suggestion on event dispatch, it is generally not good practice to call functions in the main class from a loaded one, however if you still wish to do so (calling functions in document class) this is how I usually do it:


//according to your previous code (I suppose you still want to use stage as a global reference)
//use this to access document class
stage.getChildAt(0).lift();
 
//getChildAt(0) accesses the first child of Stage, which is usually your document class in most cases.

Open in new window

0
blue-genieCommented:
i disagree ruijietan in practice, not in theory.

reason being I've been using that (whether correctly or not) successfully for the past month or so.
We're trying to access a function in the document class not the stage.
i agree as per my previous comment using dispatchers is probably a better more OOP way of doing it.
0
ruijietanCommented:
Hmm.. I thought by using your code:
StageManager(root).lift();

In a loaded movie, it would access the root of the loaded movie, not the loader?
And in that case you would be trying to type your loaded movie's root to StageManager, which would fail because the two files are not related in any way and have no reference to each other.

I have attached a sample class files which demonstrate both my method and blue-genie's method, unfortunately I cannot get blue-genie's variation to work, as you will see in comments.

Simply save both files as loader.as and external.as respectively, and associate them with two different FLA files with them as their document classes.
//SAVE THIS AS loader.as
 
package {
	import flash.display.*;
	import flash.net.URLRequest;
 
	public class loader extends Sprite {
		//vars
		public var test:String = "loader test string";
		
		private var urlReq:URLRequest = new URLRequest("external.swf");
		private var ldr:Loader;
 
		public function loader():void {
			ldr = new Loader();
			ldr.load(urlReq);
			addChild(ldr);
		}
	}
}
 
//SAVE THIS AS external.as
package {
	import flash.display.*;
	import flash.events.*;
	
	public class external extends MovieClip {
		//vars
		public var test:String = "external test string";
		
		public function external():void {
			this.addEventListener(Event.ADDED_TO_STAGE, addedToStageListener);
		}
		
		private function addedToStageListener(event:Event) {
			if (parent is Loader) {
				trace("This SWF file was loaded in by Loader.swf.");
				trace("External SWF attempting to access test string from Loader SWF's Main Class:", stage.getChildAt(0)["test"]);
				//The following code uses blue-genie's method, which if you uncomment you will see that it does not work.
				//trace("External SWF attempting to access test string from Loader SWF's Main Class alternate method:", loader(root)["test"]);
				//_lockroot is always enforced in AS3, so by referring to root here it is actually pointing to external, not loader.
				//so if you try and type/convert it to loader by using loader(root) you are trying to convert external to loader, which
				//fails because they have no relation at all.
			} else if (parent is Stage) {
				trace("This SWF was loaded standalone.");
				trace("External SWF attempting to access test string from external SWF's Main Class:", stage.getChildAt(0)["test"]);
			}
			trace("External SWF's Parent:", parent);
			trace("External SWF's Stage:", stage);
			
			
		}
	}
}

Open in new window

external.txt
loader.txt
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
gxp071Author Commented:
Thanks Guys,  

this was all really useful, and I know its a total hack, but time and needs must, Really need to get my head round the hierarchy of AS3.  And at the earliest opportunity im going to throw my self at custom event.

But for now thanks for the hack.   I'm going to split the points if that OK as you all put in your time to help.
0
gxp071Author Commented:
Thanks For all the Help!
0
blue-genieCommented:
ok i've just realised where my confusion is.
I'm sorry - didn't mean to confuse everyone on the way - to clarify.

if you've created a swf file with a document class and another one -  let's call in base file with its document class, and you load the first swf into the base file, yes you'll have an error.

sorry not thinking beyond my own breathing space.
What I'm doing when I do that is with a movieclip that i give a class linkage to and adding to the stage. and then from that class accessing the parent - not from a something with its own document class.
0
rascalpantsCommented:
just to share my personal opinion about using a document class...  

I don't.


I normally contain everything into a main_mc  movieclip and then setup a base class in the library.

Then when I have other visual assets that need their own classes within the Main, I do the same.

This is a nice way to setup bubbling for custom events.

to me, a document class just seems redundant redundant.

rp
0
blue-genieCommented:
that's interesting. thanks for that rp.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Adobe Flash

From novice to tech pro — start learning today.