I would like to dispatch an event from my class along with a url.
I know that I can do the following:
import flash.events.EventDispatcher;
private function thumbClick(e:MouseEvent):void
{
dispatchEvent(new Event("clicked"));
}
But I don't know how I would send params along with the event...?
Also, in my main app runner, I try:
var my_ev:Event = new Event("clickedImage");
my_ev.hasOwnProperty(e.currentTarget.link);
dispatchEvent(my_ev);
...but I'm not sure that this would be the correct syntax.
Thanks for any help,
jml
Allan is correct, you will want to make a custom event. Couple of things to note:
import flash.events.Event;
public class ThumbnailEvent extends Event
{
public static var THUMB_CLICKED:String = "thumbClicked";
private var _url:String;
public function get url():String { return _url }
public function ThumbnailEvent (type:String, url:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles,cancelable);
_url = url
}
override public function clone():Event
{
return new ThumbnailEvent(type, url, bubbles, cancelable);
}
}
Custom events need to always override clone. If the event is bubbled or relayed in anyway it needs this method. Custom properties should be private with a read-only getter. This is a standard convention to prevent the alteration of properties throughout the life of the event.
Using this approach would change your code to:
private function thumbClick(e:MouseEvent):void
{
dispatchEvent(new ThumbnailEvent(ThumbnailEvent.THUMB_CLICKED, myUrlString));
}
//elsewhere
addEventListener(ThumbnailEvent.THUMB_CLICKED, thumbClickedHandler);
private function thumbClickedHandler(event:ThumbnailEvent):void
{
var link:String = event.url;
}
Custom Event tutorial at adobe.com
I just make a custom event class.
import flash.events.Event;
public class ThumbnailEvent extends Event
{
public static var THUMB_CLICKED:String = "thumbClicked";
public var url:String;
public function ThumbnailEvent (type:String,url:String)
{
super(type);
this.url = url
}
}
and then use it like:
var thumbEvent:ThumbnailEvent = new ThumbnailEvent(ThumbnailEvent.THUMB_CLICKED,"myURL");
dispatchEvent(thumbEvent);
Related
Any one know how does Async.asyncHandler() work and if Async.processOnEvent() can only used in [Before] method.(Any one know some helpful document besides http://docs.flexunit.org/).
I define a MXML component named HelloCompo(extends Vbox), and the component define a function named hello(), in the hello() dispacthed a customer event named HelloEvent(the event type just named "hello"), and in another function named init() listened for the event, I want to test whether the event is dispatched properly or not. So I have the test following:
var helloCompo = new HelloCompo();
helloCompo.hello();
helloCompo.addEventListener("hello", Async.asyncHandler(this, handleHello, 1000, null, handleTimeOut));
The test will always excute the handleTimeOut method(means the HelloEvent is not dispatched, but when helloCompo.hello() excute, it really dispacthed, so what's going wrong?)
package flexUnitTests
{
import flash.events.Event;
import org.flexunit.asserts.assertTrue;
import org.flexunit.asserts.fail;
import org.flexunit.async.Async;
public class HelloTest
{
private var helloCompo:HelloCompo;
[Before]
public function setUp():void
{
helloCompo = new HelloCompo();
}
[After]
public function tearDown():void
{
helloCompo = null;
}
[Test(async)]
public function testHello():void
{
var handler:Function = Async.asyncHandler(this, helloHandler, 300, null, helloFailed);
helloCompo.addEventListener("hello", handler);
helloCompo.hello();
}
private function helloHandler(event:Event, passThroughObject:Object):void
{
//assert somthing
}
private function helloFailed(event:Event, passThroughObject:Object):void
{
fail("hello not dispatched");
}
}
}
HelloCompo.as
package
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
public class HelloCompo extends EventDispatcher
{
public function HelloCompo(target:IEventDispatcher=null)
{
super(target);
}
public function hello():void
{
dispatchEvent(new Event("hello"));
}
}
}
I think you need to add your event listener before calling hello() actually
I am trying to dispatch an custom YouTubeEvent from my Player.as and wish my Main.as would listen and create the video player...Apparently my eventHandler can't catch the event to create the videoplayer.......My flex debug mode is so screw up I can't even use it...My code is as follow..I really appreciate any reply or help.....
My custom event..
package com.youtube.events {
import flash.events.Event;
public class YouTubeEvent extends Event{
public static const PLAYER_READY:String="PLAYER_READY";
public function YouTubeEvent(type:String){
super(type);
}
}
}
My Main.as
public class SearchYoutube extends Sprite
{
private var videoPlayer:Player;
public function SearchYoutube()
{
/*********************Load Video Player****************************/
loadPlayer();
}
private function loadPlayer():void{
videoPlayer= new Player();
videoPlayer.addEventListener(YouTubeEvent.PLAYER_READY, playerReady);
//playReady would never be excuted....
}
private function playerReady(event:YouTubeEvent):void{
videoPlayer.createPlayer(); //This handler would never be executed...
addChild(videoPlayer); //This handler would never be executed...
}
}
Player.as
//only show part of codes here
public function Player(){
}
public function createPlayer():void{
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.INIT, onLoaderInit);
}
private function onLoaderInit(event:Event):void {
_loader.content.addEventListener("onReady", onPlayerReady);
}
private function onPlayerReady(event:Event):void {
dispatchEvent(new YouTubeEvent(YouTubeEvent.PLAYER_READY));
}
YouTubeEvent.PLAYER_READY is dispatched some time after calling createPlayer(). You should call createPlayer() after videoPlayer.addEventListener(YouTubeEvent.PLAYER_READY, playerReady):
private function loadPlayer():void
{
videoPlayer= new Player();
videoPlayer.addEventListener(YouTubeEvent.PLAYER_READY, playerReady);
videoPlayer.createPlayer();
}
This short tutorial will get you on the right path on using custom events with Flex.
I have instantiated a class (class1) that loads some data via PHP in an AS3 Flex project.
I instantiate class1, which is asynchronous and utilizes a URLLoader() to obtain its data.
Then I would like to instantiate class2, which needs to USE the data from class1, but when I simply instantiate it I find that class1's instance variable is not populated yet because I am calling class2 too quickly.
How can I create such a dependency that will link correctly?
I am really new to using listeners, but I am imagining a listener in class2 might be what I need?
Or maybe I can pass a reference to the listener in class1 into class2?
I also know nothing about dispatching events... is this the key?
Here's an example in pseudo code:
var class1:myC1 = new myC1("http://some/url/to/utilize");
//this never shows up because it hasn't loaded at the time i request it
trace("the stuff from class1 is: ", class1.myXMLList);
//and of course i can't use it here either
var class2:myC2 = new myC2(0x000000, class1.myXMLList);
Thanks for any help,
jml
Based on your question, I'm posting this "pseudo code" hopping it will help
package {
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.*;
public class Class1 extends EventDispatcher {
private var _loader:URLLoader;
public var data:XMLList;
public function Class1(url:String) {
_loader = new URLLoader();
_loader.addEventListener(Event.COMPLETE, completeHandler);
// rest of the code here ....
_loader.load(new URLRequest(url));
}
protected function completeHandler(event:Event):void {
data = new XMLList(_loader.data); // probably wrong but
// I figured you had already
// implemented this part
dispatchEvent(new Event(Event.COMPLETE));
}
}
}
I figured class 2 might look like this
package {
public class Class2 {
// your stuff here
public function Class2(color:uint, data:XMLList) {
}
}
}
The main class
package {
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite {
public var c1:Class1;
public var c2:Class2;
public function Main() {
c1 = new Class1("http://some/url/to/utilize");
c1.addEventListener(Event.COMPLETE, completeHandler);
}
protected function completeHandler(event:Event):void {
c2 = new Class2(0xffcc00, c1.data);
}
}
}
Hope this helps
If you want Flex/FlashBuilder to autocomplete the events for your classes, you can use the "Event" metadata tag before your class definition. Based on the example above, it would look like this
package {
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.*;
// use the "Event" metadata tag
[Event(name="complete", type="flash.events.Event")]
public class Class1 extends EventDispatcher {
private var _loader:URLLoader;
public var data:XMLList;
public function Class1(url:String) {
_loader = new URLLoader();
_loader.addEventListener(Event.COMPLETE, completeHandler);
// rest of the code here ....
_loader.load(new URLRequest(url));
}
protected function completeHandler(event:Event):void {
data = new XMLList(_loader.data);
dispatchEvent(new Event(Event.COMPLETE));
}
}
}
Now FlexBuilder/FlashBuilder should "autocomplete" the events for that class.
The downside is that you can't use "constants" with the "Event" metadata tag so this :
[Event(name=Event.COMPLETE, type="flash.events.Event")]
wouldn't work.
You can read more about event/event dispatching here.
Hope that helps :)
I have a function called DrawPlaybook which listens to two events, one mouseclick event and one custom event.
public function DrawPlaybook(...):void
{
//...... other stuff
panel.addEventListener(MouseEvent.CLICK,
function(e:MouseEvent){onClickHandler(e,this.panel)});
panel.addEventListener(CustomPageClickEvent.PANEL_CLICKED,
onCustomPanelClicked);
}
I am planning to call the custom event from within "onClickHandler" like this:
public function onClickHandler(e:MouseEvent,panel):void
{
var eventObj:CustomPageClickEvent = new CustomPageClickEvent("panelClicked");
eventObj.panelClicked = panel;
dispatchEvent(eventObj);
}
private function onCustomPanelClicked(e:CustomPageClickEvent):void {
Alert.show("custom click");
}
And here is the class definition for CustomPageClickEvent:
package
{
import flash.events.Event;
import mx.containers.Panel;
public class CustomPageClickEvent extends Event
{
public var panelClicked:Panel;
// Define static constant.
public static const PANEL_CLICKED:String = "panelClicked";
public function CustomPageClickEvent(type:String){
super(type);
//panelClicked = panel;
}
// Override the inherited clone() method.
override public function clone():Event {
return new CustomPageClickEvent(type);
}
public function getPanelSource():Panel{
return panelClicked;
}
}
}
The issue is that "onCustomPanelClicked" never gets invoked at all. Please let me know if you notice anything that I missed.
It's because you have registered the event listener for CustomPageClickEvent on the Panel, but you're dispatching it from DrawPlaybook
Just change this:
var eventObj:CustomPageClickEvent = new CustomPageClickEvent("panelClicked");
eventObj.panelClicked = panel;
dispatchEvent(eventObj)
to this:
var eventObj:CustomPageClickEvent = new CustomPageClickEvent("panelClicked");
eventObj.panelClicked = panel;
panel.dispatchEvent(eventObj)
... or change the event listener to this.addEventListener(CustomPageClickEvent.PANEL_CLICKED,
onCustomPanelClicked);.
Let me know if that works.
I am having a problem where I dispatch a custom event but the listener does not receive it (i.e. myHandler() in the code below). If I put everything in one mxml file, it works. When I separate the responsibilities in to separate classes, it fails. It is not clear to me what I am missing.
Any help you be appreciated.
Here is my code (update() in ViewModel.as is the entry point):
ChangeEvent.as
import flash.events.Event;
public class ChangeEvent extends Event
{
public function ChangeEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
// Set the new property.
this.isEnabled = isEnabled;
}
// Define static constant.
public static const ENABLE_CHANGED:String = "enableChanged";
// Define a public variable to hold the state of the enable property.
public var isEnabled:Boolean;
// Override the inherited clone() method.
override public function clone():Event {
return new ChangeEvent(type, isEnabled);
}
}
Model.as
public class Model extends EventDispatcher
{
private function TriggerEvent():void
{
var eventObj:ChangeEvent = new ChangeEvent(ChangeEvent.ENABLE_CHANGED);
dispatchEvent(eventObj);
}
}
ViewModel.as
public class ViewModel
{
import mx.controls.Alert;
import ChangeEvent;
private var model:Model;
public function ViewModel()
{
model = new Model();
addEventListener(ChangeEvent.ENABLE_CHANGED, myHandler);
}
public function update():void {
model.LoadData();
}
private function myHandler(event:Event):void {
Alert.show("An event occurred.");
}
}
Do I have to 'register' the event in ViewModel.as similar to the metadata tag in mxml?
e.g.
[Event(name="enableChange", type="ChangeEvent")]
You have to add the event listener on the model object (since it is the one dispatching the event).
model = new Model();
model.addEventListener(ChangeEvent.ENABLE_CHANGED, myHandler);
Hope that helps.