Events
Overview
One of the main features of BitsmistJS is event-driven. Each component triggers events at a particular time. When an event occurs the library prepares parameters and calls registered event handlers for that event. You build the component actions by adding code to event handlers. We will explain events here.
The events are handled by EventOrganizer.
Event types
There are two types of events in BitsmistJS. One is Javascript original events such as “click” and the other is custom events only available to BitsmistJS framework such as “doSetup”.
The custom events are implemented using standard CustomEvent and you don't need to distinguish these two types most of the time.
BitsmistJS custom event
Here is a list of the BitsmistJS custom events. In many cases, BitsmistJS events are three sets of events each name are prepended by “before”/“do”/“after”. It is meant to do the main process in events start with “do”, and its pre-process and post-process are in “before”/“after” events.
Component | Event |
---|---|
beforeStart | Do initializing process of a component. |
afterStart | |
beforeStop | Do terminating process a component. |
doStop | |
afterStop | |
beforeSetup | Apply settings to a compoent. |
doSetup | |
afterSetup | |
afterAppend | Triggered after an HTML template file is attached to a component. |
beforeRefresh | Render a component. |
doRefresh | |
afterRefresh | |
doTarget | Target data to retrieve. |
beforeFetch | Fetch data. |
doFetch | |
afterFetch |
Event handler syntax
Every event handler has a common function signature. Both Javascript original events and BitsmistJS custom events use the same format.
onDoOpen(sender, e, ex) { }
Each event handler has three parameters set by the BitsmistJS library.
sender
The component that triggered the event. For example, it is an HTMLElement clicked on “click” event, the component itself on “doSetup” event since setup() method is called by the component itself during its initialization process.
e
The Event info. It will be native event info in the case of Javascript original event. For example, this parameter is MouseEvent object for “click” event. While it is an object set by the component that triggered the event in the case of BitsmistJS custom events.
ex
The extra event info set as “options” in handler info in settings.
The handler info is an object that is set in event settings as a value to the event name.
Specifying event handlers
Specify which and when the event handlers are called in the “events” section in settings.
_getSettings() { return { "settings": { "name": "BarMain" }, "events": { "this": { "handlers": { "doSetup": this.onDoSetup } }, "btn-menu": { "handlers": { "click": this.onBtnMenu_Click } } } } }
In this example, this.onDoSetup() method is called on “doSetup” event of an element “this” (“this” means component itself). Also this.onBtnMenu_Click is called when an element that has an ID of “btn-menu” is “click”ed.
Refer to EventOrganizer reference for more details in how to set those settings.
Event handlers order
If an element has several event handlers on the same event, they are called in order as it is registered.
_getSettings() { return { "settings": { "name": "BarHeader", "path": "common", }, "events": { "this": { "handlers": { "doSetup": [ { "handler": this.onDoSetup1 }, { "handler": this.onDoSetup2, } ] } } } } }
In above example, this.onDoSetup1() is called first then this.onDoSetup2().
You can manage the order by setting a number value to the “order” option in the settings. The higher the value, the sooner the handler will be executed. The order is 0 by default.
_getSettings() { return { "settings": { "name": "BarHeader", "path": "common", }, "events": { "this": { "handlers": { "doSetup": [ { "handler": this.onDoSetup1 }, { "handler": this.onDoSetup2, "order": 10 } ] } } } } }
In above example, this.onDoSetup2() is called first, then this.onDoSetup1().
Synchronizing event handlers
Each event handler is called asynchronously. By returning a promise and calling resolve()/reject() at an appropriate timing can make the next event handler suspend until the event handler is finished.
onDoSetup1(sender, e, ex) { return new Promise((resolve, reject) => { setTimeout(() => { console.log("setup1"); resolve(); }, 2000); }); } onDoSetup2(sender, e, ex) { console.log("setup2"); }
When the above two event handlers are registered on the doSetup event, the messages are displayed in order as you expect.
setup1 setup2
What if the first handler doesn't return a promise?
onDoSetup1(sender, e, ex) { setTimeout(() => { console.log("setup1"); }, 2000); } onDoSetup2(sender, e, ex) { console.log("setup2"); }
setup2 setup1
The message “setup2” is displayed first on a console.
This was the case that one event handler has several handlers. The same is true for events that are triggered sequentially. For example, calling setup() method triggers beforeSetup, doSetup, afterSetup events sequentially. If beforeSetup event handler doesn't return a promise, then doSetup event handler will be executed before beforeSetup handler finishes its process. Return a promise whenever you want to synchronize the handlers.