Events and listeners

Events in Mapspace API follows the same objects and conventions than in OpenLayers. Every class inheriting from ol.Object has a method dispatchEvent that triggers events. Events then can be listened by instances of other classes. Every event has a name (also called type) and can send event objects to listeners in the way of objects inheriting from ol.events.Event.

Triggering events

To trigger an event call the dispatchEvent method in any class inheriting from ol.Object. This method accepts several parameters as input: an string with the name of the event, an ol.events.Event object, or a generic object with two properties (type and target) that defines the event.

For example, let's say we want to simulate a click event in a Mapspace.control.Button.

Then type this code:

var button = new Mapspace.control.Button({
    target: 'container',
    label: 'Execute'
});

// Dispatch event using a string with the name of the event
button.dispatchEvent('click');

// or using a common constant
button.dispatchEvent(Mapspace.control.EventType.CLICK);

// Dispatch event using an ol.events.Event object or any derived class
button.dispatchEvent(new ol.events.Event('click'));

// Dispatch event using a generic object
button.dispatchEvent({
    type: 'click',
    target: null
});

Now you are triggering four click events when the page is executed, but nothing happens because we are not still listening them. We will learn this in the next step.

Listening and unlistening events

Events triggered by the dispatchEvent can be consumed by instances from any other class using the static methods ol.events.listen and ol.events.listenOnce, or through the use of on and once counterpart methods in any class deriving from ol.Object.

For example, to set listeners for the click event in the Mapspace.control.Button, replace the JavaScript content with this:

var button = new Mapspace.control.Button({
    target: 'container',
    label: 'Execute'
});

// Handler for the event
var clickHandler = function(evt) {
    console.log(this.label);
};

// Listen through ol.events.listen
ol.events.listen(button, Mapspace.control.EventType.CLICK, clickHandler, button);

Now each time you click in the button you will see 'Execute' in the console log. The listen function has four parameters:

  • first is the object that triggers the events
  • second is the type of event (its name)
  • third is the function handler that will receive the event
  • last one is an optional argument with the object that will be used as this inside the handler. In this case we have passed the button object so we can say this.label in the handler.

Antoher way to listen for events is use the method on that any class inheriting from ol.Object has. So the previous code can be rewrite as follows:

var button = new Mapspace.control.Button({
    target: 'container',
    label: 'Execute'
});

// Handler for the event
var clickHandler = function(evt) {
    console.log(this.label);
};

// Listen through on
button.on(Mapspace.control.EventType.CLICK, clickHandler, button);

Listeners remain as references in the object that triggers the event unless we explicitly unlisten them. To unlisten to an event we use unlisten or un. For example, if we rewrite previous code with following code now the button do not do anything because we have removed the listener.

var button = new Mapspace.control.Button({
    target: 'container',
    label: 'Execute'
});

// Handler for the event
var clickHandler = function(evt) {
    console.log(this.label);
};

// Listen through ol.events.listen
ol.events.listen(button, Mapspace.control.EventType.CLICK, clickHandler, button);

// Unlisten through ol.events.unlisten
ol.events.unlisten(button, Mapspace.control.EventType.CLICK, clickHandler, button);

Another way to unlisten is use un. For example:

var button = new Mapspace.control.Button({
    target: 'container',
    label: 'Execute'
});

// Handler for the event
var clickHandler = function(evt) {
    console.log(this.label);
};

// Listen through ol.events.listen
ol.events.listen(button, Mapspace.control.EventType.CLICK, clickHandler, button);

// Unlisten through un
button.un(Mapspace.control.EventType.CLICK, clickHandler, button);

Another way to unlisten is called unlistenAll, which unlistens all the events listened.

var button = new Mapspace.control.Button({
    target: 'container',
    label: 'Execute'
});

// Handler for the event
var clickHandler = function(evt) {
    console.log(this.label);
};

// Listen through ol.events.listen
ol.events.listen(button, Mapspace.control.EventType.CLICK, clickHandler, button);

// Unlisten through ol.events.unlistenAll
ol.events.unlistenAll(button);

A final way to unlisten events is through the use of unlistenByKey. Any time we execute listen or on this functions return as what OpenLayers call a ListenerKey, that is an object that stores all the information of the event handling. Later we can use this object to unlisten the event easily, without the need to remember what function we use to handle the event, or what object we use as this in the handler. All that information is stored in the ListenerKey. So a more compact way of rewrite the previous code could be like this:

var button = new Mapspace.control.Button({
    target: 'container',
    label: 'Execute',
    className: 'executeButton'
});

// Handler for the event
var clickHandler = function(evt) {
    console.log(this.label);
};

// Listen through ol.events.listen
var key = ol.events.listen(button, Mapspace.control.EventType.CLICK, clickHandler, button);

// Unlisten through listener keys
ol.events.unlistenByKey(key);

Unlistening to events is important because listeners mantain references to objects. If we need to free memory listeners must be removed by the use of unlisten or similar.

Events objects sent in events

When an event is triggered we call the listener function but also we can pass one object as argument, that is called the event object. In fact OpenLayers takes care of this and always pass one argument of type ol.events.Event if we do not so.

For example, the Mapspace.control.Dropdown control triggers a click event whenever the user changes the selected option and sends an object of type Mapspace.control.DropdownEvent with the event. If you check the documentation this event object stores two values with the text and the value of the selected option.

Let's see it with an example:

var dropdown = new Mapspace.control.Dropdown({
    target: 'container',
    list: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
    listValues: [1, 2, 3, 4, 5]
});

// Handler for the event
var clickHandler = function(evt) {
    console.log('Selected ' + evt.text + ' with value ' + evt.value);
};

// Listen through ol.events.listen
dropdown.on(Mapspace.control.EventType.CLICK, clickHandler);

Now each time the Dropdown changes the selected item the text and value is outputted.