LA Flash and Flex Developer
19 May
One of the complaints I often hear about is keeping scope when using controls and/or event listeners. One of my favourite classes is the Delegate class. This class ensures scope is kept by allowing you to specify the scope when calling a method. For example:
import mx.utils.Delegate;
class Whatever extends MovieClip {
private var someClip_mc:MovieClip;
function Whatever() {
someClip_mc.onRelease = Delegate.create(this, someMethod);
}
private function someMethod():Void {
trace(this);
//this will return a reference to the movieclip that is
//attached to the Whatever class and not someClip_mc
}
}
Ok, that’s all fine and dandy, now what if you need to pass a paramater to the method you’re targeting. You could extend the Delegate class and allow for this, or you could write your own class that does the same thing but allows for paramaters to be passed. But really, who has time to do that! Below is the same example as above but this time I pass a paramater to the method.
import mx.utils.Delegate;
class Whatever extends MovieClip {
private var someClip_mc:MovieClip;
function Whatever() {
var myDel = someClip_mc.onRelease = Delegate.create(this, someMethod);
myDel.button = someClip_mc;
myDel.index = 4;
}
private function someMethod():Void {
var button:MovieClip = arguments.caller.button;
var index:Number = arguments.caller.index;
trace(button + ' has an index of ' + index);
//this will trace out someClip_mc has an index of 4
}
}
Now you may be wondering where the heck you would use this. Picture this, you are building a menu system from an xml document. You create buttons dynamically based on the amount of data, all buttons call the same method but the method needs to know what button was selected so it can set its selected state and it also needs to know the content id associated to the button selected so the appropriate content is loaded. Instead of having a seperate method for each content id/button or updating your code everytime the data is updated this allows you to write a completely dynamic menu system in the least amount of code.
Like I said above, this isn’t the best solution, but it is a solution to the fact the Macromedia forgot to add in the ability to pass an object along to the method being called. Good news is scope is not an issue in AS 3 so the Delegate class isn’t even needed.
3 Responses for "Pass parameters with the Delegate class"
This works:
var del:Function = Delegate.create(this, testArguments)(”hi”)
function testArguments (h:String):Void{
trace(h)
}
This works too:
var del:Function = Delegate.create(this, testArguments)
del (”hi”)
function testArguments (h:String):Void{
trace(h)
}
Very interesting Nicidemus, I did not realize that. Guess you learn something new everyday. I prefer another method, using AS3 where the delegate class isn’t needed anymore.
Thanks for posting this though, I’m sure others will find it very useful.
Scott
Nicidemus’s solution is cool, but it doesn’t work if you’re working with a listener method that receives an argument automatically, such as using PendingCall:
var pc:PendingCall = myWebService.myMethod(arg1, arg2);
pc.onResult = Delegate.create(this, ‘onMyMethodResult’);
…
function onMyMethodResult(result) {
// do stuff with result
}
Scott’s solution is better, otherwise the first argument you send using Nicidemus’s method will overwrite the result argument in the result listener. Also, Scott’s solution can be simplified further using the with statement:
var myDel = someClip_mc.onRelease = Delegate.create(this, someMethod);
with (myDel) {
button = someClip_mc;
index = 4;
}
Leave a reply