Events

The Event Service is used to broadcast events as topics within the App Runtime. Services which implement the EventHandler interface are informed about these events.

The Event Service is one of the core services that are required to build independent bundles that can interact with each other.

Broadcasting events

The Event Service is part of the system bundle and registered as ct.framework.api.EventService. It can be referenced by using the following definition inside a component:

Component Reference
"references": [{
  "name": "_eventService",
  "providing": "ct.framework.api.EventService"
}]

The Event Service provides two methods to broadcast an event:

  1. sendEvent synchronously broadcasts an event to the EventListeners.

    sendEvent
    // in your component code do:
    this._eventService.sendEvent("my/topic/ACTION",{propA : "event property A"});
  2. postEvent asynchronously broadcasts an event to the EventListeners. This is the recommended way of using the Event Service.

    postEvent
    // in your componente code do:
    this._eventService.postEvent("my/topic/ACTION",{ propA: "event property A"});

Listening for events

A service that wants to listen to events broadcasted by the Event Service must be registered as ct.framework.api.EventHandler and provide the service property Event-Topics.

The following kinds of listener registrations using the manifest.json file are available:

Classic Notation
// Registers a an event handler to listen on events of topic "ct/map/EXTENT_CHANGE".
{
  "name": "MyEventHandler",
  "provides": ["ct.framework.api.EventHandler"],
  "properties":{
    "Event-Topics": ["ct/map/EXTENT_CHANGE"]
  }
}

// Service Implementation
export default class {
  // 'handleEvent' is the default method name called by the Event Service to inform the listener.
  // @param evt {apprt/event/Event} the broadcasted event
  handleEvent(event) {
    // topic = 'ct/map/EXTENT_CHANGE'
    let topic = event.getTopic();

    // reason is 'EXTENT_CHANGE' (the last topic part)
    let reason = event.getTopicReason();

    let extent = event.getProperty("extent");
    // do something with the extent
  }
}
Classic Notation with filter
// Registers an event handler to listen for events of all topics starting with "ct/tool/ACTIVATE/".
// It demonstrates that you can use the wildcard '*' at the end of a topic path
// to listen on all events use the topic name '*'.
// The "Event-Filter" property allows filtering events by their properties.
// In this example the event handler is only informed about event if the event has the property "toolId" with the value 'toolA' or 'toolB'
{
  "name": "MyEventHandler",
  "provides": ["ct.framework.api.EventHandler"],
  "properties":{
    "Event-Topics": ["ct/tool/ACTIVATE/*"],
    "Event-Filter": ["(|(toolId=toolA)(toolId=toolB))"]
  }
}

// Service implementation
export default class {
  // 'handleEvent' is the default method name called by the Event Service to inform the listener.
  // @param evt {apprt/event/Event} the broadcasted event
  handleEvent(event) {
    let toolId = event.getProperty("toolId");
    // do something with the ID
  }
}
Topic Object Notation
// Here the topic object notation is shown.
// It allows to map topics to individual methods in the EventHandler instance.
{
  "name": "MyEventHandler",
  "provides": ["ct.framework.api.EventHandler"],
  "properties":{
    "Event-Topics": [{
      "topic":"ct/tool/ACTIVATE/toolA",
      "method":"_handleActivationOfToolA"
    }]
  }
}

// Service implementation
export default class {
  // @param evt {apprt/event/Event} the broadcasted event
  _handleActivationOfToolA(event) {
    var toolId = event.getProperty("toolId");
    // do something with the ID
  }
}
Topic Object Notation with multiple topics to one method
// This example demonstrates the use of the topic object notation to map multiple topics to one method.
{
  "name": "MyEventHandler",
  "provides": ["ct.framework.api.EventHandler"],
  "properties":{
    "Event-Topics": [{
      "topic":["ct/tool/ACTIVATE/toolA","ct/tool/ACTIVATE/toolB"],
      "method":"_handleActivationOfTool"
    }]
  }
}

// Service implementation
export default class {
  // @param evt {apprt/event/Event} the broadcasted event
  _handleActivationOfTool(event) {
    var toolId = event.getProperty("toolId");
    // do something with the ID
  }
}
Topic Object Notation with filter
// This sample shows the usage of the topic object notation and the direct configuration of a filter within this topic object
{
  "name": "MyEventHandler",
  "provides": ["ct.framework.api.EventHandler"],
  "properties":{
    "Event-Topics": [{
      "topic":"ct/tool/ACTIVATE/*",
      "method":"_handleActivationOfToolA",
      "filter" : "(toolId=toolA)"
    }]
  }
}

// Service implementation
export default class {
  // @param evt {apprt/event/Event} the broadcasted event
  _handleActivationOfToolA(event) {
    var toolId = event.getProperty("toolId");
    // do something with the ID
  }
}
Topic object notation with parameter binding
// This sample shows the usage of the topic object notation with the pre-configuration of handler method params
{
  "name": "MyEventHandler",
  "provides": ["ct.framework.api.EventHandler"],
  "properties":{
    "Event-Topics": [{
      "topic":"ct/tool/ACTIVATE/toolA",
      "method":"_switchActivate",
      "params" : [true]
    },
    {
      "topic":"ct/tool/DEACTIVATE/toolA",
      "method":"_switchActivate",
      "params" : [false]
    }]
  }
}

// Service implementation (does not know that it is an EventHandler)
export default class {
  // @param flag {boolean} a flag provided by the configuration
  _switchActivate(active /*, event // is still provided */) {
    if (active) {
      // do if active
    } else {
      // do if not active
    }
  }
}