Skip to content
Andrea Campolonghi edited this page Aug 17, 2010 · 8 revisions

Event definition

When CFEM dispatch an event a special object is created, populated and passed as only arguments to the chain of the subscribed listeners. By default
CFEM create an instance of “com.andreacfm.cfem.events.Event”.

You can craete your own event type but rememeber that you must implement “com.andreacfm.cfem.events.AbstractEvent” to make your own event allowed by CFEM.
To achieve this is quite easy :

component extends="com.andreacfm.cfem.events.Event"{
}

While com.andreacfm.cfem.events.Event is already an implementation of the Abstract class extending Event is all what you need.

Event Properties

  • Name : String – Required : Any event has a name that must be unique in the CFEM instance.
  • Type : String : The full class package of the dispatched event. Default = com.andreacfm.cfem.events.Event
  • Mode : String – Default = synch ( options : asynch ) : An event can be runned in syncronous or asyncronous way.
  • Data : Struct – Deafult = {} : Data is an internal store where the event carry any kind of informations you need the event to pass to the listeners or just keep in his internal state.
  • Target : Any : Target represent the point from where the event has been dispatched. If dispatched from a cfc you normally pass “this” to the event as target.

Any time you dispatch an event a new event is generated and passed to the listeners chain. The recomended way is to ask CFEM for an event instance, configure
it for your needs and pass the event to CFEM for the dispatching proceed. Example:

var data = { mykey = value };
var event = CFEM.createEvent(name = 'myEvent', data = data, target = this);
CFEM.dispatchEvent(event);

If event is dispathced in sync mode at this point I still have a reference to the event after that all the listeners has been called. So if for example
a listeners added something to the internal data I could collect that information.

var DataAfterAllListenersHasBeenCalled = event.getData();

If you are not interested in a later use of the event in your template you could also use this syntax (to be preferred for async events ):

CFEM.dispatchEvent(name = 'myEvent', data = { mykey = value }, target = this);

Methods

  • StopPropagation : void : Any event has an internal state. CFEM check this state before any listener invocation. Calling this method prevents CFEM to follow the listeners chain. Any listeners still in the queue wil nver be invoked.
//Listener
public void function onMyEvent(com.andreacfm.cfem.events.Event event){
	if (......){
		event.StopPropagation();
	}
}

Think carefully what kind of code you could prevent to be executed and what cab be the conseguences.

  • isActive : Boolean : Tells you what the event state is. This will be more handy when you develop a custom event than in normal operation.
  • getEventId : String : Return a unique id based on the underlying java class implemetation. This is NOT the event name.

Interceptions

See more about interceptions and actions how-to here.

Any event has a 3 interceptions point.

  • Before : before the first listener is invoked.
  • Each : after the invocation of any listener.
  • After : after the last listener as been invoked.

Any event has an internal property called “point” that trace exactly the point reached by the event in the listeners chain. The interceptions are stored into the event object using an observer/observable pattern.

  • isObserved : Boolean : Tells if any object is registered as observer ( in any cut point ).
  • getPoint : String : The point reached by the event in his life flow.
  • updatePoint : void : Normally called by CFEM will make the event update his internal point trace and call any registered Observer.

CollectDataEvent

Many times you will find to use events that has the only goal to collect data. Imagine a blog engine that prepare the sidebar display and needs to know what ‘pods’ will be displayed.

While an event is a normal cfc and you can attach things anywhere you like CFEM comes with a special events designed just for collecting data.

Use a collect data event is very easy, it justs means to provide to CFEM the right the when the event is registered :

CFEM.addEvent(name = "myevent", type = "com.andreacfm.cfem.events.CollectDataEvent");
// If defined with cfem xml notation  
<events>        
        <event name="oneEvent" class="com.andreacfm.cfem.events.CollectDataEvent"/>
 		.......	

See more about xml notation.

A CollectDataEvent is just a normal event with an internal array called items and some methods exposed to manage it:

  • getItems : Array : Return all the items.
  • addItems : void : Add an array of items to the existings items.
  • addItem : void : Add a single item

An example:

We have an event called ‘onSidebarStart’ that is dispatched before our blog engine display the sidebar.

<cfscript>
var event = CFEM.createEvent('onSideBarStart');
CFEM.dispatchEvent(event);
var pods = event.getItems();
</cfscript>
//display the pods
<cfloop array="#pods#" index="pod">
	<cfoutput>
		<h1>#pod.title#</h1>
		<p>#pod.body#</p>
	</cfoutoput>
</cfloop>

Event is fired. Any subscribed listeners is called and the the pods are displayed.

//This listener subscribed to the event
public void function onSideBarStart(Any event){
	var pod = {
		title = 'Categories',
		body = 'coldfusion,railo,eclispe'
	}
	event.addItem(pod);
} 

There could be just this listener and only one pod will be displayed or there might be more listeners registered and anyone will add more pods ( or remove etc…). How cool is that? The core code that display the pods will never change but output will dynamically manipulated by the listeners activity. Do you see ? Your app is now extensible with no need to change the core itself.

Clone this wiki locally