Home Tutorials Forums Articles Blogs Movies Library Employment Press
Old 06-04-2005, 09:24 PM   #1
madgett
is my last name...
 
Join Date: May 2004
Posts: 1,051
Default Using the mx.utils.Delegate class within your classes!

The Delegate class is very useful in large projects with many classes. I’ve read many posts of problems where scope in classes is lost through the dynamic MovieClip class and other classes and their various events, an example is mc.onPress.

The Delegate class will solve this problem. Follow the class examples to understand the power of using this class in your applications.

The code below is an example of what happens when Delegate is not used:
ActionScript Code:
// This class draws a clickable box on the screen class Testdel {     // Private variables     private var mc:MovieClip;     private var number:Number = 5;     // Constructor function     public function Testdel() {         mc = _root.createEmptyMovieClip("mc", 0);         with (mc) {             lineStyle(1, 0xFF0000);             beginFill(0x00000, 0);             lineTo(0,0);             lineTo(100,0);             lineTo(100,100);             lineTo(0,100);             lineTo(0,0);             endFill();         }         mc.onPress = function() {             showNumber(); // Doesn't call             trace(number); // Traces undefined even though we defined it above as a private property         }     }     public function showNumber(Void):Void {         // Display the class property: number         trace (number);     } }
To test the class place var a:Testdel = new Testdel(); on the main timeline of a FLA in the same directory as the class. Notice in the class above where we have the function:
ActionScript Code:
mc.onPress = function() {             showNumber(); // Doesn't call             trace(number); // Traces undefined         }
When the MovieClip is pressed, it will not call showNumber and number will trace undefined. Why? → The scope of the function is pointing at the MovieClip mc not at the Class. We need to point the scope to the class. So the logical solution was to just use local class variables to defeat the scope issue:
ActionScript Code:
var ScopeOfClass:Testdel = this; mc.onPress = function() {             ScopeOfClass.showNumber(); // Now this will call the class method trace(ScopeOfClass.number); // Now this will display 5 in the output panel }
Now because we pointed the scope of the class to ScopeOfClass local variable, it will call the function and display the trace statements in the output panel.

But! This is not the most convenient way. What if you wanted to change 20 class variables or call more methods inside mc.onPress? Then you would have to copy and paste ScopeOfClass before every method and property! Not efficient at all.

How to get the same effect without copy and pasting ScopeOfClass?? By using mx.utils.Delegate. Here is what the class looks like when you incorporate the Delegate class:
ActionScript Code:
import mx.utils.Delegate; class Testdel {     private var mc : MovieClip;     private var number : Number = 5;     public function Testdel ()     {         mc = _root.createEmptyMovieClip ("mc", 0);         with (mc)         {             lineStyle (1, 0xFF0000);             beginFill (0x00000, 0);             lineTo (0, 0);             lineTo (100, 0);             lineTo (100, 100);             lineTo (0, 100);             lineTo (0, 0);             endFill ();         }         mc.onPress = [b]Delegate.create (this, showNumber);[/b]     }     public function showNumber (Void) : Void     {         // Display the class property: number         trace (number);     } }
Notice that the scope inside showNumber() points to the Class and not to the MovieClip.

Now to see it not working try this:
ActionScript Code:
mc.onPress = showNumber; // Put this trace statement inside [b]showNumber()[/b] trace(this); // Notice how this will now output the reference to the MovieClip, the scope is no longer pointing to the class
trace(number); that is inside showNumber() will be undefined because of the scope pointing to the MovieClip mc, instead of the Class.

For a tutorial, visit the one here on ActionScript.org: http://www.actionscript.org/tutorial...ss/index.shtml
__________________
Anything is possible with Flash, it's just a matter of inventing the possibilities
Certified Swfwizard

Last edited by madgett; 07-22-2005 at 02:45 AM. Reason: import should be: mx.utils.Delegate not util
madgett is offline   Reply With Quote
Old 06-14-2007, 04:19 PM   #2
gianni
Registered User
 
Join Date: Apr 2007
Posts: 3
Default

For some reason Delegate.create() isn't calling my class method.

Here is the method that uses delegate:

Code:
function loadXML():Void {
	trace("Adding onLoad handler via delegate");
	this.xml.onLoad = Delegate.create(this, receiveXML);
	this.xml.load(url);
}
And this is the method that is supposed to be called by delegate:

Code:
function receiveXML(success) {
	trace("receiveXML called");
	
	// Initialise Data
	if (success) {
		trace("Successfully loaded file");
		// Create Chapters
		for(var i:Number=0; i<this.xml.chapter.length; i++) {
			trace("Loaded Chapter " + i);
			var chapter = this.xml.chapter[i];
			this.chapters.push(chapter);
		}
	}
	
	trace("Executing user callback");
	// User onLoad
	this.onLoad(success);
}
This code worked when I didn't use delegate and I just passed references to the things I needed, but in the future it will be more complicated and I would like to use delegate. Any Ideas?

Gianni
gianni is offline   Reply With Quote
Old 06-27-2007, 11:10 AM   #3
krismeister
Registered User
 
Join Date: Jun 2007
Posts: 4
Default

I know this is a slightly older thread, but I found it searching for a usage example using XML.

gianni:
Make sure you're declaring the xml as a var at the top of the class:

Code:
class SomeClass{
	private var _xml:XML;

	public function loadXML(url:String):Void {
		_xml= new XML;
		trace("Adding onLoad handler via delegate");
		_xml.onLoad = Delegate.create(this, receiveXML);
		_xml.load(url);
	}
	private function receiveXML(success:Boolean):Void{
		trace(success);
		trace(this);
		trace(_xml);
	}
}
krismeister is offline   Reply With Quote
Old 09-02-2007, 11:11 PM   #4
goncabrita
Registered User
 
Join Date: Sep 2007
Posts: 1
Default

What if you want to use delegate inside your class and have both access to the class to call its methods and to the object (like a movie clip) that triggered the function in order to use it properly?

'Cause right now I cant seem to do both at the same time, I either access the class or know the object that called the class function...
goncabrita 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 11:15 AM.

///
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.