One of my favorite libraries is Vue. There’s a cool feature in this library that I want to steal for my Angular projects — Event modifiers.

From the Vue documentation —

It is a very common need to call event.preventDefault() or event.stopPropagation() inside event handlers. Although we can do this easily inside methods, it would be better if the methods can be purely about data logic rather than having to deal with DOM event details.

I very much agree with the author, call me crazy, but when I write code like this:

I want to throw up on the screen. 🙈

To address this problem, Vue provides event modifiers for v-on. Recall that modifiers are directive postfixes denoted by a dot.

So in Vue you can do this:

Let’s implement this in Angular. This will be our final result:

First, we need to create the directive and inject two things, the ElementRef and the Renderer service. ( In Angular version 4 you will use Renderer2 )

The next thing that we need is an Output . As you may know, you can’t use the dot notation and write something like this:

@Output() click.stop = new EventEmitter();

The dot notation only works with property names which are valid identifier names.

🙏 Fortunately, Output takes an optional parameter that specifies the name used when instantiating a component in the template, or in a simple word — an alias.

@Output("click.stop") stopPropEvent = new EventEmitter();

When you pass an alias, it’s like using the bracket notation so you can use any character sequence as a property name.

OK, this was the tricky part, the rest should be piece of 🍰.

We can register a new click event with the help of the Renderer service passing the native element, the event name and handler.

When the user clicks on the element, we call the stopPropagation() method and emit the event.

Without the directive —

With the directive —

Note: You can still pass the $event and any other data to your handler, it’s the same behavior as the original (click) event.

<button class="child" (click.stop)="fromChild($event, data)">

Click me

</button>

Follow me on Medium or Twitter to read more about Angular, Vue and JS!