Is there a way to dispatch a SWFAdresss CHANGE Event but also pass parameters (an Object) along with it?
I see something like that in the documentation but I can't find an example online...
You could modify the SWFAddressEvent class like so:
private var _customObject:Object;
public function SWFAddressEvent(type:String, customObject:Object, bubbles:Boolean = false, cancelable:Boolean = false) {
super(type, bubbles, cancelable);
_customObject = customObject;
}
and then when you dispatch the CHANGE event, add the object to the Event:
dispatchEvent(SWFAddressEvent.CHANGE, customObject);
To make the Object publically available:
public function get publicCustomObject():Object
{
return _customObject;
}
Related
Is there any simple -- or suggested -- way in order to send a parameter along with a custom event? Or even just a way to pass variables between two classes?
My program is a sort of simple Civ/Age of Empires kind of game, where you can place buildings on tiles. This would work as follows:
Player clicks on the icon on the HUD, which creates an dispatches an event which is received by the PLAYER class.
The PLAYER class changes a value depending on which building is held (clicked on).
Player clicks on the tile in the grid to place it, which dispatches an event which is received by the PLAYER class.
The PLAYER class creates a building object and adds it to an array within the PLAYER class.
An example of how I'd want the code to work:
icon.as
private function onMouseClick(e:MouseEvent = null):void {
var iconClickedEvent:Event = new Event("BUILDING_HELD", buildingType); // passes "buildingType" through the event somehow
stage.dispatchEvent(iconClickedEvent);
}
tile.as
private function onMouseClick(e:MouseEvent = null):void {
var buildingPlacedEvent:Event = new Event("BUILDING_PLACED", xRef, yRef);// passes "xRef" & "yRef", the tile's co-ordinate
stage.dispatchEvent(buildingPlacedEvent);
}
player.as
private function init(e:Event):void {
stage.addEventListener("BUILDING_HELD", buildingHeld(buildingType));
stage.addEventListener("BUILDING_PLACED", placeBuilding(xRef, yRef));
}
private function buildingHeld(building:int):void {
buildingType = building;
}
private function placeBuilding(xRef:int, yRef:int):void {
switch(buildingType){
case 1: // main base
MainBaseArray.push();
MainBaseArray[length-1] = new MainBase(xPos, yPos); // create new object with the references passed
break;
}
}
The best way to manage this is to create custom event classes for each of your events (or event types).
If you create a class that inherit Event, it will be usable in the same ways that a standard Event, but can contain custom values or methods.
Here's an example of such class :
public class BuildingEvent extends Event {
// contains an event name. Usefull to ensure at compile-time that there is no mistape in the event name.
public static const BUILDING_HELD:String = "BUILDING_HELD";
private var _buildingType:int;
// the constructor, note the new parameter "buildingType". "bubbles" and "cancelable" are standard parameters for Event, so I kept them.
public function BuildingEvent(type:String, buildingType:int, bubbles:Boolean = false, cancelable:Boolean = false) {
super(type, bubbles, cancelable);
_buildingType = buildingType;
}
// using a getter ensure that a listening method cannot edit the value of buildingType.
public function get buildingType() {
return _buildingType;
}
}
We can then use this class like this :
// to dispatch the event
private function onMouseClick(e:MouseEvent = null):void {
var iconClickedEvent:BuildingEvent = new BuildingEvent(BuildingEvent.BUILDING_HELD, buildingType);
stage.dispatchEvent(iconClickedEvent);
}
// to listen to the event
private function init(e:Event):void {
stage.addEventListener(BuildingEvent.BUILDING_HELD, buildingHeld);
}
private function buildingHeld(event:BuildingEvent):void {
buildingType = event.buildingType;
}
Is it possible to pass a var at the end of an addEventListener?
/// clickType declared elsewhere in code.
checkBoxFast.addEventListener(clickType, goFast("yes"));
function goFast(evt:Event=null,myVar:String)
{
trace(myVar);
}
I guess if you want to parametrize your event handing I would suggest passing variables to the Event.
-Create a custom event:
public class MyEvent extends Event {
public var myVar:String;
public function MyEventHistoryEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) {
super(type, bubbles, cancelable);
}
}
-Dispatch this event from the event dispatcher with the required variable:
var event:MyEvent = new MyEvent("eventType");
event.myVar = "yes";
dispatchEvent(event);
-Add an event handler:
checkBoxFast.addEventListener("eventType", eventHandler);
protected function eventHandler(event:MyEvent):void {
trace(event.myVar);
}
Another solution would be to use an anonymous function like so:
checkBoxFast.addEventListener(clickType, function(e:Event):void{goFast("yes")});
function goFast(myVar:String)
{
trace(myVar);
}
Creating custom event is best way I guess. But I was using sometimes different aproach. I dont know if it is good practice but it works in some cases.
public function test() {
var myVar : String = "some value";
addEventListener(MouseEvent.CLICK, onClick);
function(e:Event){
trace(myVar);
}
}
Here's a pretty clean way:
checkBoxFast.addEventListener(clickType, goFast("yes"));
function goFast(myVar:String) {return function(e:Event) {
trace(myVar);
}}
BUT beware anonymous functions, they won't let you end the listener in the same place it was made! If you keep repeating it like that many times in your application, it may get slow and freeze.
Actually, I really recommend you to do it like this:
var functionGoFast:Function = goFast("yes");
checkBoxFast.addEventListener(clickType, functionGoFast);
function goFast(myVar:String):Function {
return function(evt:Event = null):void {
trace(myVar);
}
}
//checkBoxFast.removeEventListener(clickType, functionGoFast);
See this answer for more examples and explanations on your case.
Can any one give me a simple example on how to dispatch an event in actionscript3 with an object attached to it, like
dispatchEvent( new Event(GOT_RESULT,result));
Here result is an object that I want to pass along with the event.
In case you want to pass an object through an event you should create a custom event. The code should be something like this.
public class MyEvent extends Event
{
public static const GOT_RESULT:String = "gotResult";
// this is the object you want to pass through your event.
public var result:Object;
public function MyEvent(type:String, result:Object, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.result = result;
}
// always create a clone() method for events in case you want to redispatch them.
public override function clone():Event
{
return new MyEvent(type, result, bubbles, cancelable);
}
}
Then you can use the code above like this:
dispatchEvent(new MyEvent(MyEvent.GOT_RESULT, result));
And you listen for this event where necessary.
addEventListener(MyEvent.GOT_RESULT, myEventHandler);
// more code to follow here...
protected function myEventHandler(event:MyEvent):void
{
var myResult:Object = event.result; // this is how you use the event's property.
}
This post is a little old but if it can help someone, you can use DataEvent class like so:
dispatchEvent(new DataEvent(YOUR_EVENT_ID, true, false, data));
Documentation
If designed properly you shouldn't have to pass an object to the event.
Instead you should make a public var on the dispatching class.
public var myObject:Object;
// before you dispatch the event assign the object to your class var
myObject = ....// whatever it is your want to pass
// When you dispatch an event you can do it with already created events or like Tomislav wrote and create a custom class.
// in the call back just use currentTarget
public function myCallBackFunction(event:Event):void{
// typecast the event target object
var myClass:myClassThatDispatchedtheEvent = event.currentTarget as myClassThatDispatchedtheEvent
trace( myClass.myObject )// the object or var you want from the dispatching class.
I get some weird errors when creating CustomEvent, it appears Event being extended does not give access to Event properties:
package
{
import flash.events.Event;
public class CustomEvent extends Event
{
//public static const COMPLETE:String = 'complete';
private var _assetName:String;
public function get assetName ():String
{
return _assetName;
}
public function set assetName ( aname:String ):void
{
_assetName = aname;
}
public function CustomEvent (type:String, bubbles:Boolean = false, cancelable:Boolean = false)
{
super (type, bubbles, cancelable);
}
public override function clone ():Event
{
return new CustomEvent(type, bubbles, cancelable) as Event;
}
}
}
When doing:
myObj.addEventListener(CustomEvent.COMPLETE, objLoaded);
I get error that COMPLETE doesnt exist... Ok, i set it to the place and then it caomplains about cannot convert CustomEvent to Event.
What am i missing here ??
You need to declare this public static const COMPLETE:String = 'complete'; as static var/const are not transfered to extending classes.
The error about converting CustomEvent to Event may be caused by setting event listener to listen to the Event not CustomEvent.
Where is the event dispatched and what does the signature of the listener look like?
We've got a few issues to cover here:
You have your public static const COMPLETE... commented out. Why? That's needed if you want to refer to CustomEvent.COMPLETE as the event type.
Using my psychic third eye, you've got your event listener declared like this:
public completeListener(evt:Event):void
...
That's not going to work the way you want it to. You need
public completeListener(evt:CompleteEvent):Void
...
Unrelated to the compilation issue, your custom event has another issue. Your clone method is not going to clone the assetName property. Try something like this:
public override function clone():Event
{
var ret:CustomEvent = new CustomEvent(type, bubbles, cancelable);
ret.assetName = assetName;
return ret;
}
I am creating a library. Here is an example
[Event (name="eventAction", type="something")]
public function create_new_customer(phone_number:String):void
{
-------------;
----;
------------;
rpc.addEventListener(Event.COMPLETE, onCreate_returns);
}
private function onCreate_returns(evt:Event):void
{
var ob:Object = evt.target.getResponse();
dispatchEvent(new something("eventAction"));
}
I have a listener to this event in app side. So when I manually dispatch event I want the
"ob" to be sent as a parameter. How to do it?
You need to create a custom event class with extra properties to pass data with it. In your case you could use a class like
public class YourEvent extends Event
{
public static const SOMETHING_HAPPENED: String = "somethingHappend";
public var data: Object;
public function YourEvent(type:String, data: Object, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.data = data;
}
override public function clone():Event
{
return new YourEvent (type, data, bubbles, cancelable);
}
}
then when yo dispatch you do:
dispatchEvent(new YourEvent(YourEvent.SOMETHING_HAPPENED, ob));
In AS3 you can use DataEvent:
ex:
dispatchEvent( new DataEvent(type:String[,bubbles:Boolean=false,cancelable:Boolean=false, data:String ] );
Instead of example data, I showed the parameters DataEvent takes.
I hope this helps.
Best regards, RA.
Make your custom event carry this ob object. Pass it to the custom event's ctor and voila!