Should a custom event have get methods? - actionscript-3

I created some custom events in a desktop application and gave it some get methods in order to grab the data that is associated with the event. It seems odd to be calling 'get' methods on an event. Is this bad programming practice, should I make the event properties public instead?
Here is my custom event...
package classes.events
{
import flash.events.Event;
public class ListItemClickedEvent extends Event
{
public static var PROJECT_CHOSEN:String = "project_chosen";
private var projectName:String;
private var projectLabel:String;
private var projectFolder:String;
public function ListItemClickedEvent(type:String, bubbles:Boolean = true,
cancelable:Boolean = false, pName:String = null,
pLabel:String = null, pFolder:String = null){
super(type, bubbles, cancelable);
projectName = pName;
projectLabel = pLabel;
projectFolder = pFolder;
}
override public function clone():Event{
return new ListItemClickedEvent(type, bubbles, cancelable);
}
public function getProjectName():String{
return projectName;
}
public function getProjectLabel():String{
return projectLabel;
}
public function getProjectFolder():String{
return projectFolder;
}
}
}

Flex events like ListEvent or MenuEvent simply use public variables, but feel free to use any access practice you like: getter functions, properties or public variables. It's your class and you can use your own style.

Related

AS3 CustomEvent not being extended at all?

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;
}

Cleaning ArrayCollections

Initially I had ten arraycollections declared in a flex module, which I thought, were causing a memory leak. So I separated them in a single class, which I would clean using the "destroy" method I created inside it. Would this work?
I hate the question title excuse me. But I wouldn't write it like "Seducing the garbage collector"
[Bindable]
public class Cfd
{
private static var instance:Cfd = new Cfd();
private var _cfds:ArrayCollection = new ArrayCollection();
// Constructor
public function Cfd(){
if (instance) { throw new Error('Cannot create a new instance. Must use Cfd.getInstance().') }
}
public static function getInstance():Cfd{
return instance;
}
public function get cfds():ArrayCollection{
return _cfds;
}
public function set cfds(value:ArrayCollection):void{
_cfds = value;
}
public function destroy():void{
if(_cfds != null){
_cfds.removeAll();
}
}
}
Whenever you use Singletons like this, you pretty much guarantee a memory leak, because you're probably listening to the ArrayCollection (and maybe items within it) from all over the place. When you explicitly provide a reference to an object through a getter/setter pair, you can add the listener in the setter and removie it when the value is reset.
Check out http://www.developria.com/2010/08/rethinking-addeventlistener-an.html for more on what's happening.
For more on why you should avoid Singletons http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars
Just null the object should do it unless you have listeners attached to it.
cfds = null;
I have never seen [Bindable] used on the class itself, so not sure what you are trying to do there.
package{
public final class Cfd{
private static var instance;
private var _cfds:ArrayCollection = new ArrayCollection();
public function Cfd(singletonEnforcer:MySingletonEnforcer){
if (instance) { throw new Error('Cannot create a new instance. Must use Cfd.getInstance().') }
}
public static function getInstance():Cfd{
if (instance == null)
instance = new MySingleton(new MySingletonEnforcer());
return instance;
}
// don't see a real need for setter/getters here
public static function get cfds():ArrayCollection{
return _cfds;
}
public static function set cfds(value:ArrayCollection):void{
_cfds = value;
}
// I wouldn't even use a destroy on this class since it is a singleton.
// just set the data to null Cfd.cfds = null
public static function destroy():void{
_cfds = null
}
}
}
//this is in Cfd.as but is outside the package block
class MySingletonEnforcer {}

How to implement Custom Events?

How do I correctly implement custom events? I thought the following should work, but I never receive CustomEvent.READY in the main Model
package mvc
{
import flash.events.Event;
public dynamic class CustomEvent extends Event
{
public static const MY_EVENT:String = "myEvent";
public static const READY:String = "ready";
public function CustomEvent(type:String)
{
super(type);
}
}
}
In the Model.as which extends AbstractModel which extends EventDispatcher
private function initWorld():void {
_worldModel = new WorldModel();
_worldModel.addEventListener(CustomEvent.READY, update);
}
Then in WorldModel.as which extends AbstractModel which extends EventDispatcher, I dispatch an event, but update is never called. why?
dispatchEvent(new Event(CustomEvent.READY));
_worldModel.dispatchEvent(new CustomEvent(CustomEvent.READY));
You must instantiate a CustomEvent, not an Event. Big difference.
You could also use your custom event to pass additional parameters with the dispatched event, which will prove amazingly handy if you make use of your CustomEvent heavily
package com.b99.events
{
import flash.events.Event;
/**
* ...
* #author bosworth99
*/
public class AppEvents extends Event
{
public static const APP_READY :String = "application ready";
public static const XML_LOADED :String = "XML has loaded";
public static const CHANGE_COMPLETE :String = "state change complete";
public static const PAGE_ADDED :String = "page content added";
public static const PAGE_REMOVED :String = "page content removed";
public static const LIBRARY_LOADED :String = "external library loaded";
public static const IMAGE_LOADED :String = "external image loaded";
public static const LOAD_ERROR :String = "external load failed";
public var arg:*;
public function AppEvents(type:String, bubbles:Boolean = false, cancelable:Boolean = false, ...a:*)
{
super(type, bubbles, cancelable);
arg = a;
}
override public function clone():Event
{
return new AppEvents(type, bubbles, cancelable, arg);
}
}
}
You can then pass any number of arguments along to a receiving function:
this.dispatchEvent(new AppEvents(AppEvents.LIBRARY_LOADED, false , false, _name, _library, _names));
And access them in the recieving function as an array.
private function onLibraryLoad(e:AppEvents):void
{
_digestExternalLib.removeEventListener(AppEvents.LIBRARY_LOADED, onLibraryLoad);
var currentIndex:int = AppData.navLocations.indexOf(e.arg[0], 0);
AppData.libraries.push(e.arg[0]);
AppData.libraryCon.push(e.arg[1]);
AppData.libraryNames.push(e.arg[2]);
}
I yanked this from a functioning project... but you should be able to gather the important bits...
Good luck!
I don't really see anything wrong with the code. Just to test, try adding this statement at the end of initWorld() method:
_worldModel.dispatchEvent(new Event(CustomEvent.READY));
If your update() method is called, that would indicate that your existing dispatchEvent() method isn't being called.

How to create a bean in ActionScript?

I have created a bean class in action script using flash builder getters and setters method.
the class is :`
package default{
public class AccountBean
{
private var _username:String;
private var _email:String;
public function get username():String {
return _username;
}
public function set username(value:String):void {
_username = value;
}
public function get email():String {
return _email;
}
public function set email(value:String):void {
_email = value;
}
public function AccountBean() {
}
}
}
How to use set and get methods for this, is this creation of class is correct or not? please help
Yes, it's correct!
var bean:AccountBean = new AccountBean();
//using the setters
bean.username = "Whatever";
bean.email = "bean#whatever.com";
//using the getters
trace( bean.username , bean.email ); // Whatever bean#whatever.com

Override Clone() in custom event for AS3... need help

I have created a custom even class which is pretty basic. But when calling an event and then relaying that event to another class I have encountered the "cannot transform thisEvent into thisOtherEvent" error.
I realize this is because I needed to override the Clone function in my custom event like so:
package com
{
import flash.disply.*;
import flash.events.Event;
public class MyCustomEvents extends Event
{
public static const SOME_EVENT:String = "some_event";
public var info:Object;
public function MyCustomEvents($type:String, $info:Object,$bubbles:Boolean = false, $cancelable:Boolean = false)
{
super($type, $bubbles, $cancelable);
this.info = $info;
}
public override function clone():Event {
return new MyCustomEvents($type, $bubbles, $cancelable);
}
}
}
However I am still getting this error when I dispatch the event. Anything else I might be missing?
here is the error:
TypeError: Error #1034: Type Coercion failed: cannot convert com.greensock.events::TransformEvent#d8df709 to com.customEvents.MyCustomEvents.
I tried casting the event in the code like so:
var deleteImgEvent:MyCustomEvent = new MyCustomEvent(MyCustomEvents.IMAGE_DELETE, {imgData: getImg}, true, false); this.dispatchEvent(deleteImgEvent as MyCustomEvents);
Still no luck.
UPDATE:
Ok, seems like the problem is in the greensock Transform library. When the event handler for my custom event is called, I run a function of the TransformManager class.
_manager.deleteSelection();
Inside that class it dispatched a TransformEvent. Not sure why, but it is reading that delete event as a MyCustomEvent.
/**
* #usage
* var myEvent:CustomEvent = new CustomEvent(CustomEvent.EVENT_TYPE_A, { integerRelatedToEvent: 5, stringRelatedToEvent: 'easy' });
* addEventListener(CustomEvent.EVENT_TYPE_A, traceCustomEvent);
* dispatch(myEvent);
* function traceCustomEvent ($e:CustomEvent):void {
* trace($e.type);
* }
*/
package {
import flash.events.Event;
public class CustomEvent extends Event {
// Types:
public static const EVENT_TYPE_A:String = 'CustomEvent.EVENT_TYPE_A';
public static const EVENT_TYPE_B:String = 'CustomEvent.EVENT_TYPE_B';
// Components:
private var _customDatum:Object;
public function get customDatum ():Object { return _customDatum; }
public function CustomEvent ($type:String, $customDatum:Object) {
super($type);
_customDatum = $customDatum;
}
public override function clone ():Event {
return new CustomEvent(type, _customDatum);
}
}
}
"When creating your own custom Event
class, you must override the inherited
Event.clone() method in order for it
to duplicate the properties of your
custom class. If you do not set all
the properties that you add in your
event subclass, those properties will
not have the correct values when
listeners handle the redispatched
event."
package com.events;
{
import flash.events.Event;
public class XMLLoaderEvent extends Event
{
public static const XML_LOADED:String = "XML_Loaded";
public var data:*;
public var properties:Object;
public function XMLLoaderEvent( type:String,_data:*,bubbles:Boolean = false,cancelable:Boolean = false):void
{
super( type, bubbles, cancelable );
data = _data;
}
// Override clone
override public function clone():Event
{
return new XMLLoaderEvent( type, data, bubbles, cancelable);
}
}
}
Don't know if that's it but you have an extra parameter $info:Object into your custom event, but you don't pass it in your clone contructor.
return new MyCustomEvents(type, info, bubbles, cancelable);
I think you need the clone function to return a MyCustomEvents type. Not an Event type. And you need to add the info parameter as stated by the previous poster.
package com {
import flash.display.*;
import flash.events.Event;
public class MyCustomEvents extends Event {
public static const SOME_EVENT:String = "some_event";
public var info:Object;
public function MyCustomEvents($type:String, $info:Object,$bubbles:Boolean = false, $cancelable:Boolean = false) {
super($type, $bubbles, $cancelable);
this.info = $info;
}
public override function clone():MyCustomEvents {
return new MyCustomEvents(this.type, this.info, this.bubbles, this.cancelable);
}
}
}