Encapsulate common behaviors with the aid of Angular directives
Today React cowboys are celebrating another release of the library which provides so-called hooks. I’ve heard that the hooks give a chance to easily reuse common logic.
In this post I’ll present how to achieve the same goal in Angular. The example is taken from a real world application.
Let’s say that you want to play a sound when a button within a navigation is clicked. The application contains several pages and each one has a navigation consisting of buttons.
Forget about DRY
If you forgot about the DRY (Don’t Repeat Yourself), you could accomplish the goal in the following way.
Create the service:
Of course, in a real world application I used a package called Howler to play sounds.
Render each page and register the click handler for each navigation’s button:
and define the playSound method within a component’s class:
Note, that I need to repeat the same code for each page, namely a callback definition and the callback registration for each button.
The need for refactor is clear!
Meet directives
Fortunately, you can encapsulate the common behavior, namely playing a sound upon click event, within a directive:
It’s far better than the initial solution, since you define the click callback just once. However, in order to apply the directive to a button, you need to add the appClickSound attribute to each button:
You’ve definitely improved the previous solution, since the click handler is defined in a single place. As a result, you can easily change the behavior and testing gets easier.
However, you can do better!
Use native selector
A directive’s selector can be any valid CSS selector such as an element selector. With the above code, the ClickSoundDirective instance will be applied to each button within the nav tag.
As a result, you no longer need to add an extra attribute to the navigation’s buttons:
Conclusions
It always puts a smile on my face when I hear React cowboys celebrating new features which has already been present in the Angular framework 😃