Home Tutorials Forums Articles Blogs Movies Library Employment Press

Go Back   ActionScript.org Forums > ActionScript Forums Group > ActionScript 2.0

Reply
 
Thread Tools Rate Thread Display Modes
Old 01-27-2005, 03:40 PM   #1
dvanbrunt
Registered User
 
dvanbrunt's Avatar
 
Join Date: Jan 2005
Location: Toronto, ON
Posts: 4
Question Referencing Issue? Function can't be called.

I've done a bunch of searching and can't seem to find the answer to this issue. I'm coding an ActionScript Class that will eventually build a dynamic flash menu based on an XML doc. I've refenced a bunch that I have seen around but they all seem pretty messy.

Here's my issue.

Code:
class dynamicMenu {
	private var clip:MovieClip;
	private var xmlDoc:XML;
	// CONSTRUCTOR
	public function dynamicMenu(menuName:String, target:MovieClip, depth:Number, x:Number, y:Number, xmlURL:String, menuOrient:String) {
		clip = target.createEmptyMovieClip(menuName, depth);
		loadXML(xmlURL);
	}
	public function loadMenu():Void {
		trace("Function --loadMenu-- Hit");

	}
	public function loadXML(newURL:String):Void {
		var menuXML = new XML();
		menuXML.ignoreWhite = true;
		menuXML.onLoad = function(success) {
			if (success) {
				trace("XML Loaded");
				xmlDoc = menuXML;
				loadMenu();
			} else {
				trace("connectionFailed");
			}
		};
		menuXML.load("danMenu.xml");
	}
}
loadMenu(); DOESN'T get called but trace("XML Loaded"); DOES. Is this a referencing issue? I'm I going about this wrong?

Any help would be greatly apprieciated, including if anyone has any good dynamic flash menu (XML) examples.

- Dan
dvanbrunt is offline   Reply With Quote
Old 01-27-2005, 04:15 PM   #2
Trevor Harrison
Lurking since 2004
 
Join Date: Apr 2004
Location: Maryland, USA
Posts: 48
Send a message via AIM to Trevor Harrison
Default

Quote:
Originally Posted by dvanbrunt
Code:
	public function loadXML(newURL:String):Void {
		var menuXML = new XML();
		menuXML.ignoreWhite = true;
		menuXML.onLoad = function(success) {
			if (success) {
				trace("XML Loaded");
				xmlDoc = menuXML;
				loadMenu();
			} else {
				trace("connectionFailed");
			}
		};
		menuXML.load("danMenu.xml");
	}
}
Yeah, the "this" in your menuXML.onLoad func isn't a dynamicMenu "this", its a XMLNode "this".

My recommendation: use Delegate.

ActionScript Code:
class dynamicMenu {     private var clip:MovieClip;     private var xmlDoc:XML;     // CONSTRUCTOR     public function dynamicMenu(menuName:String, target:MovieClip, depth:Number, x:Number, y:Number, xmlURL:String, menuOrient:String)     {         clip = target.createEmptyMovieClip(menuName, depth);         loadXML(xmlURL);     }     public function loadMenu():Void     {         trace("Function --loadMenu-- Hit");     }     function onXMLLoad( success : Boolean )     {         if (success)         {             trace("XML Loaded");             loadMenu();         } else         {             trace("connectionFailed");         }     }     public function loadXML(newURL:String):Void     {         xmlDoc = new XML();         xmlDoc.ignoreWhite = true;         xmlDoc.onLoad = mx.Utils.Delegate.create(this, onXMLLoad);         xmlDoc.load("danMenu.xml");     } }

or if you don't want to stash the in-progress xml object in your class, try something like:

ActionScript Code:
public function loadMenu( loadedXMLdoc : XML ):Void     {         xmlDoc = loadedXMLdoc;         trace("Function --loadMenu-- Hit");     }     public function loadXML(newURL:String):Void     {         var menuthis = this;         var menuXML = new XML();         menuXML.ignoreWhite = true;         menuXML.onLoad = function(success)         {             if (success)             {                 trace("XML Loaded");                 menuthis.loadMenu(this);             }             else             {                 trace("connectionFailed");             }         };         menuXML.load("danMenu.xml");     } }

-Trevor
Trevor Harrison is offline   Reply With Quote
Old 01-27-2005, 04:30 PM   #3
dvanbrunt
Registered User
 
dvanbrunt's Avatar
 
Join Date: Jan 2005
Location: Toronto, ON
Posts: 4
Default

I think your first solution is a bit over my head. If you don't mind explaining a bit more, what are the major differences in the two ways you have solved this? How with either effect other code?

Thanks
dvanbrunt is offline   Reply With Quote
Old 01-27-2005, 04:34 PM   #4
dvanbrunt
Registered User
 
dvanbrunt's Avatar
 
Join Date: Jan 2005
Location: Toronto, ON
Posts: 4
Default

Sorry, I should also ask....I'm I even going about this the right way? Or is there an easyier/better way to organise it?
I'm pretty new to AS classes.
dvanbrunt is offline   Reply With Quote
Old 01-27-2005, 04:53 PM   #5
Trevor Harrison
Lurking since 2004
 
Join Date: Apr 2004
Location: Maryland, USA
Posts: 48
Send a message via AIM to Trevor Harrison
Default

Quote:
Originally Posted by dvanbrunt
I think your first solution is a bit over my head. If you don't mind explaining a bit more, what are the major differences in the two ways you have solved this? How with either effect other code?

Thanks
Well, they are kinda similar, but the important thing to remember is that pointing an object's method to a new function that you supply

(ie. xmlDoc.onLoad = function() { blah blah; }; )

is _injecting_ the function into the xmlDoc instance that you have. So, when that function gets executed, its executed in the context of the xmlDoc object. Not in any other context (ie. your object) The same thing applies with injecting a function from your class into the xmlDoc.... ie:

xmlDoc.onLoad = myXMLOnLoad;

where

ActionScript Code:
class myClass {   function myXMLOnLoad()   {     trace("blah");     foo();   }   function foo()   {   } }

myXMLOnLoad is a func in your class. However, as soon as you do the xmlDoc.onLoad = myXMLOnLoad; statement, when it gets executed, its as if the code was really in the XML.as file instead of the myClass.as file. Trying to call foo() won't work. Because XML.as doesn't have a foo() func.

To get around this, so that you can execute your func in your own context, you can use Delegate to get back to your context, or you can create a function object that points to your context and calls back to you.

ie. in my example, I had a

ActionScript Code:
var menuthis = this;

I should have highlighted it somehow. Its the important piece. This allows the function that you are creating to get back to your object and call something there.... ie:

ActionScript Code:
menuXML.onLoad = function(success)         {                 if (success)                 {                         trace("XML Loaded");                         menuthis.loadMenu(this)// <---- call back to myself                 }

In this case, calling back to the myMenu object, its loadMenu method, and passing a parameter (the "this") of the XML doc that just got finished loading.

Delegate does the same thing, but Macromedia just wrapped it up in a utility class for you.

The return value of the Delegate.create() is a function that will call back into your object's context and invoke a method there.

-Trevor
Trevor Harrison is offline   Reply With Quote
Old 01-27-2005, 04:54 PM   #6
Trevor Harrison
Lurking since 2004
 
Join Date: Apr 2004
Location: Maryland, USA
Posts: 48
Send a message via AIM to Trevor Harrison
Default

Quote:
Originally Posted by dvanbrunt
Sorry, I should also ask....I'm I even going about this the right way? Or is there an easyier/better way to organise it?
I'm pretty new to AS classes.
You're doing it correctly.

-Trevor
Trevor Harrison is offline   Reply With Quote
Old 01-27-2005, 06:07 PM   #7
dvanbrunt
Registered User
 
dvanbrunt's Avatar
 
Join Date: Jan 2005
Location: Toronto, ON
Posts: 4
Default

Thanks a bunch Trevor! You have been a BIG help clearing up that issue.....I knew it had "something" to do with referencing out of context, just that I didn't know what context I was in.

I went with your second solution and it works perfect. Now off to find out why flash is caching old code when I ctrl+enter. Grrrrr side issues are always fun.

Thanks Again!

Last edited by dvanbrunt; 01-27-2005 at 06:21 PM. Reason: mistype
dvanbrunt is offline   Reply With Quote
Old 01-27-2005, 08:04 PM   #8
ash_ljs
Registered User
 
Join Date: Apr 2004
Posts: 48
Default

You can put the onLoad function actually in your class to make things cleaner

At the top of your class file:
import mx.utils.Delegate;

In your class:
ActionScript Code:
function onXMLLoad(success) {             if (success) {                 trace("XML Loaded");                 xmlDoc = menuXML;                 loadMenu();             } else {                 trace("connectionFailed");             }

Inside loadXML():

menuXML.onLoad = Delegate.create(this, onXMLLoad);

Now, loadMenu and xmlDoc will be in scope.
ash_ljs is offline   Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump


All times are GMT. The time now is 01:23 PM.

///
Follow actionscriptorg on Twitter

 


Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Ad Management plugin by RedTyger
Copyright 2000-2013 ActionScript.org. All Rights Reserved.
Your use of this site is subject to our Privacy Policy and Terms of Use.