views:

59

answers:

5

Hi there!

I got a question about event dispatching in flex.

my goal is to get a custom event loaded up with some data and than bubble up to the eventlistener.

my main application has and AMF service request inside which calls an service class. that class is supposed to dispatch an event when the AMF service request returns a result or fault and the main application is listening for that event.

so inside my mainapp i add and listener like this:

this.addEventListener("UserInfoEvent", userInfoHandler);

the custom UserInfoEvent.as looks like this

package events
{
 import flash.events.Event;

 import logic.Ego;

 public class UserInfoEvent extends Event
 {
  private var ego:Ego;

  public function UserInfoEvent(type:String, ego:Ego)
  {
   super(type);
   this.ego = ego;
  }

  override public function clone():Event 
  { 
   return new UserInfoEvent(type, ego);
  } 
 }
}

and finally the dispatcher inside the AMF Service class looks like this:

private var dispatch:EventDispatcher = new EventDispatcher;  
var userInfoEvent:UserInfoEvent = new UserInfoEvent("UserInfoEvent", ego);
dispatch.dispatchEvent(userInfoEvent);

However, this event never reaches the main application. Looking closely to it with the debugger, i found out that when the event is dispatched the listeners property of it is set to null.

Can anyone tell me what i'm doing wrong?

+2  A: 

I think your event is not getting caught because it doesn't bubble

instead of

super(type);

try

super(type, true, false);

If you call the Event constructor with one argument, it defaults to false for the other two arguments, one of which is bubbles.

I think your other problem is that you're creating a new EventDispatcher. Instead, extend EventDispatcher with your service class and then just call dispatch().

Fletch
Yes you need to bubble up.
jase21
i tried that. no luck. when looking at it with the debugger the event gets created, bubbleing is set to true, but its currenttarget and target properties are null. AS doc says that currentdoc is the listenerevent currently listening for that event - since it's null i suppose thats the problem, but i don't know what i'm doing wrong.
masi
OK I edited my response as you also have an EventDispatcher issue.
Fletch
I think it's a combination of this and quoo's answer
DyreSchlock
i'll try extending the class and notify you on success.
masi
nope, no luck...
masi
A: 

I'm guessing your event dispatcher is bubbling up to the systemManager rather than up through the main app since your dispatcher is not added as a child of the main app. Try adding your listener to the systemManager rather than the main app itself:

this.systemManager.addEventListener("UserInfoEvent", userInfoHandler);
Wade Mueller
Tried that, dosn't work. Also i forgot to mention that the service class is instantiated inside the mainapp, so the dispatcher should be bound to it (one bubble level up).
masi
+1  A: 

So events in Flex are identified by their string names. Your Event class doesn't have a 'name', so it doesn't have any way of identifying it and matching it when it's dispatched. This 'name' is what's passed into the 'type' parameter of the constructor. It's traditionally stored and referenced as a static constant. Since you're comparing the class object UserInfoEvent to a string "UserInfoEvent" it never matches and catches that this is the event that you want to handle.

package events
{
    import flash.events.Event;

    import logic.Ego;

    public class UserInfoEvent extends Event
    {

        public static const MY_EVENT:String = "myEvent";
        private var ego:Ego;

        public function UserInfoEvent(type:String, ego:Ego)
        {
            super(type);
            this.ego = ego;
        }

        override public function clone():Event 
        { 
            return new UserInfoEvent(type, ego);
        } 
    }
}

And then you'd listen / dispatch this event using:

dispatchEvent(new UserInfoEvent(UserInfoEvent.MY_EVENT));

and

addEventListener(UserInfoEvent.MY_EVENT, myEventHandler);

Hopefully that makes sense, i'm fighting off a nasty migraine right now and it's killing my ability to use words:P

quoo
And as Fletch said, you'll want to bubble your event most likely.
quoo
yeh after looking at some more examples i've seen that and tried adding a string to it like in your example, but after all, it didn't work. but i'll keep it in so i can dispatch different events with one eventclass. So: any more ideas guys?
masi
+1  A: 

You are not listening to the event in the right way as I see it.

 // you have 
 this.addEventListener("UserInfoEvent", userInfoHandler);

 // but you dispatch the event from    
 dispatch.dispatchEvent(userInfoEvent);  

which is wrong

You need to have something like

instance_of_Dispatch.addEventListener();  // because this != dispatch
Adrian Pirvulescu
but why should i add and eventlistener to an eventdispatcher? afaik the eventlistener listens for events that bubble trough the component they listen to, which is the main application in my case. the eventdispatcher dispatches the event which then bubbles up to the root, right trough the main app, which listens for that event bubbel and preforms the defined funtion.
masi
Events only bubble up through the display list - a service class would not be part of the display list, so it wouldn't bubble up to your view. You might want to read more about events in AS3 - try this: http://www.communitymx.com/content/article.cfm?cid=76FDB
quoo
A: 

OK, so it looks like everybody was right abit.

here the hole solution:

MainApplication.mxml important to mention here is that this only works if the service class extends the sprite class, otherwise you can't use the addEventListener method. looks like another solution for that is to implement the IEventDispatcher

private var service:MyService = new MyService;
this.service.addEventListener(UserInfoEvent.RESULT, userInfoHandler);

UserInfoEvent.as

package events
{
    import flash.events.Event;
    import logic.user.Ego;

    public class UserInfoEvent extends Event
    {
        private var ego:Ego;
        public static var RESULT:String = "resultEvent";

        public function UserInfoEvent(type:String, ego:Ego)
        {
            super(type,  true, false);
            this.ego = ego;
        }

        override public function clone():Event 
        { 
            return new UserInfoEvent(type, ego);
        } 
    }
}

And finally, as allready mentioned, the sprite extended MyService.as

public class MyService extends Sprite
{
...
userInfoEvent = new UserInfoEvent(UserInfoEvent.RESULT, ego);
dispatchEvent(userInfoEvent);

so that worked for me. Thanks for all your help guys, i'll mark Adrian's answer as correct since it gave me a direction.

masi