In Angular we can extend the events binding syntax. Let's add posibility to log an event before firing a handler.
Create custom event plugin:
import { Injectable } from '@angular/core';
import { EventManager, ɵgetDOM as getDOM } from '@angular/platform-browser';
/**
* A plug-in that logs event to the console before firing.
*
* ```html
* <button (click.log)="handler()">Handle&log</button>
* ```
*
* **Warning**: it can not be stacked with another plugin-based handlers. Like key events (e.g. `(keydown.alt)`) or hammer gestures
* (e.g. `(swipe)`). `EventManager` uses only one suitable plugin.
*/
@Injectable()
export class EventsLogPlugin {
/**
* The manager will get injected by the EventPluginManager at runtime.
*/
manager!: EventManager;
/**
* Check that event has `.log` suffix.
*/
supports(eventName: string): boolean {
return !!this.parseName(eventName);
}
/**
* Registers a handler for an event.
*/
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
const outsideHandler = (event: any) => {
// Log event before calling handler.
console.log('Event log', {element, eventName, event});
// Run handler in the zone.
this.manager.getZone().runGuarded(() => handler(event));
};
// Add event listener and return listener remover.
return this.manager.getZone().runOutsideAngular(() => {
return getDOM().onAndCancel(element, this.parseName(eventName), outsideHandler);
});
}
private parseName(eventName: string) {
const parts: string[] = eventName.toLowerCase().split('.');
const domEventName = parts.shift();
if (parts.indexOf('log') !== -1) {
return domEventName;
}
}
}Register the plugin in the root module:
...
import { BrowserModule, EVENT_MANAGER_PLUGINS } from '@angular/platform-browser';
import { EventsLogPlugin } from './events-log-plugin';
@NgModule({
...
providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: EventsLogPlugin,
multi: true,
},
],
})
export class AppModule {
}Use the new feature:
<button (click.log)="handler($event)">Click me and check the console</button>