Alex Rivera | Logout

Passing parameters to event listeners / handlers

Asked 2009-09-23T09:27:19.820
10

How do you pass parameters / variables through event listeners? I've overcome this problem fairly effectively using anonymous functions; which is an incredibly simple solution, but at the end of the day, it smells like a giant loophole for functionality that I feel should be provided natively anyways.

Normally life would go on, but as fate would have it, now I actually need to remove the listener, and doing so when you've using an anonymous function is a bit funky. So, once again, I'm trying to figure out how to pass parameters through to event listeners so that the event listeners can be removed by simply referencing the function.

As odd as it may seem, I've overcome this issue as well, BUT, I don't like it and tired of using it. In my opinion it is code smell. But it works like a charm. I store the variable, object or whatever on the dispatching MovieClip. So, if I'm looping though an array of data, generating thumbnails on the fly, I simply store the data variable (normally an object with multiple properties) in the actual thumbnail MovieClip. Then I can access all the data in an event listener method by referencing:

event.target.data
. In this example, "data" is the name of the variable holding holding the information I want. Because another issue that crops up when I don't use this is, is that when I'm looping through an array and generating thumbnails that click to view large images, the index is not consistent. At the end of the loop, ALL the thumbails will all open an image using the last index of "i". So if I had an array with a length of 12, they'd all load the 12th image regardless of what thumbnail you clicked on. Storing the data into the MovieClip itself, creates a solid reference that never changes.

This has been bothering me for some time now. Basically what I want to know is, is this good practice, are there better solutions out there?

Below are some diet examples.

Edit
Report

3 Answers

1

You can use what's called "Delegates" if you don't like storing the data in the target member. Neither is better than the other. It's mostly just preference.

Here's an example of a Delegate class (nothing built-in): http://www.actionscript.org/resources/articles/205/1/The-Delegate-Class/Page1.html

That's probably the best idea if the eventdispatcher isn't your own class. Otherwise, storing the variable in your own class isn't a bad idea at all. Just OOP style.

Cheers.

answered 2009-09-23T09:44:53.747
0

You can do the following, which basically is a cleaner way of passing custom data.

example code:
public function myCustomEvenListener(e:MouseEvent,myCustomData:Object)
{
//Do whatever you wnat with myCustomData Object here...
}
//this is the function where you add event listeners to components..
public function init():void
{
var myCustomObject:Object=new Object();
myCustomObject.url="http://xyz.com/image.jsp";
myCustomObject.anydata="You can Add anything here";

mycomponent.addEventListener(MouseEvent.CLICK,function (e:MouseEvent) : void {
                  myCustomEventListener(e,myCustomObject);
            });

}

This is just another way of using anonymous functions though....

answered 2009-09-23T10:54:47.477
0

It is probably better practice to make a custom class that extends MovieClip for your thumnbnail, and have that thumbnail dispatch a custom Event class that has a place to store your data:

Make a custom URLEvent that can store the url property along with the event

package{

import flash.events.Event;

public class URLEvent extends Event{

    public var url:String;
    public static const CLICK:String = "URLEventClick"

    public function URLEvent(type:String, url:String = "", bubbles:Boolean = false, cancelable:Boolean=false){
        super(type, bubbles, cancelable);
        this.url = url;
    }

    override public function clone():Event{
        return new URLEvent(type,url,bubbles,cancelable);
    }
  }
}

Make a custom thumbnail class that can store the url variable, and sends a URLEvent when clicked:

package{

import flash.display.MovieClip;
import flash.events.MouseEvent;

public class Thumbnail extends MovieClip{

    protected var url:String;

    public function Thumbnail(url:String){
        this.url = url;
        addEventListener(MouseEvent.CLICK,clickHandler);
    }

    //the thumbnail captures its own click and dispatches a custom event
    protected function clickHandler(event:MouseEvent):void{
        dispatchEvent(new URLEvent(URLEvent.CLICK,url));
    }

}

Now you can use your Thumbnail class to load each image:

tempThumb.addEventListener(URLEvent.CLICK,tempThumbClickHandler);

function tempThumbClickHandler(event:URLEvent):void{
//we can get the url property direct from the URLEvent
    loadImage(event.url);
}

This method is much better OOP practice, as you do not need to know what type of object your event.target is - you know from the event type exactly what type of data will be sent with each event.

answered 2009-09-23T23:22:24.427

Your Answer