Skip to content

Event Handling

Swiz handles event using the Mediate metadata annotation.

When you set mediateBubbledEvents in the SwizConfig to true your views can simply dispatch an event which is then captured by the Swiz DynamicMediator. The class containing the Mediate has to be a class defined in a BeanLoader or a view in the display chain.

Simple Event

View code:

// note that the event must set bubbles to true
dispatchEvent(new Event("fooEvent", true))

Controller code:

[Mediate(event="fooEvent")]
public function fooHandler():void{//...}

Typed Event

Event class:

package example.event
{
	import flash.events.Event;
 
	public class FooEvent extends Event
	{
		public static const FOO:String = "foo";
 
		public var someValue:String;
 
		public function FooEvent(type:String, someValue:String, bubbles:Boolean=true, cancelable:Boolean=false)
		{
			super(type, bubbles, cancelable);
			this.someValue = someValue;
		}
 
		override public function clone() : Event
		{
			return new FooEvent(type, someValue, bubbles, cancelable);
		}
	}
}

View code:

dispatchEvent(new FooEvent(FooEvent.FOO, "example"))

Controller code:
When you want the short notation you have to set SwizConfig eventPackages=”example.event” and SwizConfig strict to true.

[Mediate(event="FooEvent.FOO", properties="someValue")]
public function fooHandler(someValue:String){//...}

When Swiz resolves the Mediate metadata it will evaluate

  • if the class example.event.FooEvent exists
  • if the class has a static const FOO
  • if the class has a public member someValue

If anythings fails Swiz will throw an Error. Behind the scenes the values of the FOO constant is evaluated which is “foo” in this case.
So in general the example above is equivalent to this:

[Mediate(event="foo", properties="someValue")]
public function fooHandler(someValue:String):void{//...}

But with this notation you don’t get runtime validation so when you have a typo like the following you will be in the dark debugging your code:

[Mediate(event="fooo", properties="someValue")]
public function fooHandler(someValue:String):void{//...}

Priorities

If you mediate an event in multiple classes you might want to control the order of how the dynamic mediators are invoked. For that reason Swiz leverages the Event priorities:

[Mediate(event="FooEvent.FOO", properties="someValue", priority="0")]
public function secondFooHandler(someValue:String):void{//...}
[Mediate(event="FooEvent.FOO", properties="someValue", priority="1")]
public function firstFooHandler(someValue:String):void
{
// I am called first because of higher priority
}

Passing the Event
Instead of passing properties of an event to the mediating function you can also pass the event itself.

[Mediate(event="FooEvent.FOO")]
public function fooEventHandler(event:FooEvent):void

Controlling Event Flow

With the event reference you get other options like stopping the propagation.
We will take a slightly modified version of the priority example:

[Mediate(event="FooEvent.FOO", properties="someValue", priority="0")]
public function secondFooHandler(someValue:String):void{//...}
[Mediate(event="FooEvent.FOO", priority="1")]
public function firstFooHandler(event:FooEvent):void
{
	// when we call this the event won't bubble further meaning secondFooHandler will never be invoked
	event.stopImmediatePropagation();
}

Working with cancelable Events

When you set the cancelable property of the event to true you get another flexibility which can become handy.
Let’s assume you have a popup which dispatches an event. Depending on some controller logic the popup should be closed or stay open. Now you might think the controller needs a reference to the view but it won’t.
View code:

if(dispatchEvent(new FooEvent(FooEvent.FOO, "test", true, true))
{
	PopupManager.closePopup(this);
}
else
{
	// do something when the event was canceled
}

Controller code:

[Mediate(event="FooEvent.FOO")]
public function fooEventHandler(event:FooEvent):void
{
	// when we call this dispatchEvent in the view will return false
	event.preventDefault();
}

Dispatch Events from non-view classes

You can also dispatch events from non-view classes like for instance a controller class which can then be handled by Swiz.
You have got three different options:

  1. Use the static Swiz method:
    Swiz.dispatchEvent(new FooEvent(FooEvent.FOO, "test"));
  2. The BeanLoader has a protected property of the dispatcher which you directly set into your bean:
    <ctrl:SomeController id="someController" dispatcher="{dispatcher}" />
  3. Your bean implements the IDispatcherBean interface.
    private var _dispatcher:IEventDispatcher;
    public function set dispatcher(dispatcher:IEventDispatcher):void
    {
    	_dispatcher  = dispatcher;
    }

{ 1 } Trackback

  1. [...] type check the event object and the event type to make sure they exist — check it out in the Swiz Docs for Event Handling — or you can save yourself some extra code and do what I did. While I’m usually a [...]