EventProxy.as : Proxying Events
One of the issues I ran into while building the MXNA WebService example app, was that both the ComboBox and DataGrid both broadcast “change” events. This meant that I could not have a separate function to listen for each event (and have the functions run within the scope of the feedView class).
There were two solutions to this. The first was to have a switch statement in my change event handler, that checked the eventObt.target property to see where the event came from. I could then dispatch the call as appropriate. Here is an example of what the event handler would look like:
private function change(eventObj:Object)
{
switch(eventObj:target)
{
case myDataGrid :
{
//the datagrid event fired
break;
}
case myComboBox :
{
//the combobox event fired
break;
}
}
}
However, I personally don’t like this as it means I have to define an event handler, maintain a switch statement, and then define individual methods to handle the events. Jesse Warden posted a good example of this on his weblog.
The other option was to create a simple class that basically proxies the events to different scopes and methods. I like this solution as it felt a little cleaner to me. I put together a simple proxy class (EventProxy) based on a FlashCoder’s post by Sam Neff.
Here is an example of how it works (from MXNAFeedView.as):
public function onLoad(Void):Void
{
categoryProxy = new EventProxy(this, "onCategorySelect");
category_cb.addEventListener("change", categoryProxy);
feedGridProxy = new EventProxy(this, "onFeedGridSelect");
feedDG.addEventListener("change", feedGridProxy);
}
//broadcast by ComboBox when user selects an item in the combo
private function onCategorySelect(eventObj:Object):Void
{
//ComboBox change event fired
}
//broadcast by the DataGrid when the user selects a row
private function onFeedGridSelect(eventObj:Object):Void
{
//datagrid change event fired
}
This does two things:
- It allows change events from two different components to be dispatched to two methods.
- It allows the event handlers to be called within the scope of the containing class (in this case MXNAFeedView)
Here is the code for the class:
/*
EventProxy class
Allows:
-scope of events to be changed
-events calls to be proxied to arbitrary functions
*/
class com.macromedia.mesh.events.EventProxy
{
private var receiverObj:Object;
private var funcName:String;
/*
Constructor:
-receiverObj : the receiverObj in which the event will be called
-the function name to be called in response to the event
*/
function EventProxy(receiverObj:Object, funcName:String)
{
this.receiverObj = receiverObj;
this.funcName = funcName;
}
//this is called before the event is broadcast by the components
private function handleEvent(eventObj:Object):Void
{
//if not function name has been defined
if(funcName == undefined)
{
//pass the call to the event name method
receiverObj[eventObj.type](eventObj);
}
else
{
//pass the call to the specified method name
receiverObj[funcName](eventObj);
}
}
}
Post any suggestions or bugs in the comments.