PDA

View Full Version : Function arguments with Listeners?



lonerhino
June 28th, 2007, 12:29 PM
Yikes, Sorry but I'm really having problems migrating to AS3 :puzzled:

A big conceptual hole I can't seem to wrap my head around is how do you pass parameter arguments with listeners? Forget classes for right now - baby steps - I cannot even figure out the basics in calling functions on the timeline! All code on frame 1 of main.

Here's my old style function with sample call


// Function to load items
function gearLoader(sItem,nSide):Void{

this["btn" + sItem].onRelease = function(){
mcItem.loadMovie(sItem + ".swf");
mcItem._x = nSide;
tDesc.text=lvItemDesc[sItem];
tTitle.text=lvItemTitle[sItem];
tTitle.setTextFormat(tfTitleFormat);
mcProducts._alpha=30;
}

}

//sample call
gearLoader(“goggles”, 244);

So now, in AS3, I set up my loader instance and register my button listeners.

var swfLoader:Loader = new Loader();
var sRequest:URLRequest = new URLRequest("boots.swf");

//add to display list
addChild(swfLoader);

//event handling - subscribe listeners
swfLoader.contentLoaderInfo.addEventListener(Event .COMPLETE,handleImage);

btnRod.addEventListener(MouseEvent.CLICK, gearLoader);
btnVest.addEventListener(MouseEvent.CLICK, gearLoader);
btnWadeBoots.addEventListener(MouseEvent.CLICK, gearLoader);
btnHat.addEventListener(MouseEvent.CLICK, gearLoader);
btnHelmet.addEventListener(MouseEvent.CLICK, gearLoader);
btnBoots.addEventListener(MouseEvent.CLICK, gearLoader);
btnGoggles.addEventListener(MouseEvent.CLICK, gearLoader);
btnGloves.addEventListener(MouseEvent.CLICK, gearLoader);


function handleImage(evtObj:Event):void{
//set initial position onstage
swfLoader.y = 56;
swfLoader.x = 244;
}

So how do I pass the necessary parameters to the function below in a reasonably simple way? I've used event.target.name of a listener event object in other AS3 Projects to determine button clicked. . .but again, that does not help me with parameters.

New Function
function gearLoader(sItem:String, nSide:Number):void{

//dim Bitmap
mcProducts.alpha = 30;

//position clip
swfLoader.x = 244;

//fetch a swf
swfLoader.load(new URLRequest(sItem + ".swf"));

}

I've looked through help files & articles but I'm certain I'm missing something simple here. Thanks Much!

NaughtyPine
June 28th, 2007, 01:30 PM
listeners pass instances of the function you are firing the event from.

You target the data via your event and .target

lonerhino
June 28th, 2007, 02:42 PM
Thanks Naughty,

Could you me more specific or point me to an example?

Dazzer
June 28th, 2007, 10:36 PM
There isn't a real way of passing parameters to a EventListener. The most common way is to construct your own Event class (extend the Event class) and put in the necessary variables (+ accessors) thus being able to access them from the event instance.

For example, the ProgressEvent is a subclass of the Event class, but it has additional variables for bytesLoaded and bytesTotal, which can be accessed within the event listener.

lonerhino
July 1st, 2007, 01:23 PM
Thanks for the reply Dazzer - I think that's a bit beyond what I'm trying to accomplish here though.

If it's not possible to pass function arguments when using addEventListener() , then is the common approach to let the listener function make the call to yet another function that does have parameters - such as the example below?

btnMove.addEventListener(MouseEvent.CLICK, onClick);


function onClick(evtObj:MouseEvent):void{

moveClip(mcBox, 10);

}


function moveClip(target:MovieClip, amount:Number):void{

target.x += amount;

}

axiomflash
August 1st, 2007, 02:56 PM
Hi Lonerhino, I know a month has passed since you asked this question, but I found it on the google machine and wanted to follow up.

Have you found any solutions to this other than custom event listeners, and how is it working out for you? I've been wrestling with this problem myself. i just can't bear to actually write a custom event class for each time I need to do this. Perhaps it is best practice, but it seems really heavy-handed.

Here is the hack I've been using to solve this problem:
First I create a class var (at the top of the class)

private var _obj:Object = new Object();
//this is a catchall for saving vars that don't need a really need a unique class var. this is a really bad practice, but without it we would need custom events to pass parameters from a listener to a function.

then at my event listener:

myButton.addEventListener('click', myFunction);

private function myFunction(eventObj:Object = null){
_obj.updateValues_ignore = "knobs"
updateValues(eventObj);
}

private function updateValues(eventObj:Object = null):void {
if(_obj.updateValues_ignore != 'knobs'){
//update knobs
knobLow_sp.x = calcKnobLocation('low');
knobHigh_sp.x = calcKnobLocation('high');
}
if(_obj.updateValues_ignore != 'textFields'){
//update textfields
}
return;
}


The trouble with this is (a) It's just sloppy and I lose type checking, and (b) I need the intermediary function myFunction();

geoken
August 1st, 2007, 03:21 PM
You can attach whatever you're trying to send to the actual button/clip.

For example;

myButton.someVar = 'knobs'

then, in the function that's bieng called by the listener you just reference 'event.currentTarget.someVar'

jman1
August 2nd, 2007, 02:02 AM
Here is an example of adding using properties from a dispatcher. See the code in Bold that references the event parameter:

private var _fileRef:FileReference = new FileReference();

_fileRef.addEventListener(ProgressEvent.PROGRESS,p rogressHandler);

private function progressHandler(event:ProgressEvent):void {
_statusBar.mode="manual";
var temp:Number= event.bytesLoaded - _uploadedBytes2[event.target.name];
_uploadedBytes2[event.target.name]= event.bytesLoaded;
_uploadedBytes+= temp;
_statusBar.setProgress(_uploadedBytes,_totalBytes) ;
_statusLabel.text=GetSizeType(_uploadedBytes);
_statusLabel3.text=GetSizeType(_totalBytes) + " loaded.";
}

Hope this helps.

J-Man