In Angular 1, directives are a way for developers to extend HTML. This means
introducing new behaviours to the DOM via custom tags or attributes. You can
change what a directive matches by using the
restrict option. By default it
is set to
'EA', meaning it works on elements (tags) and attributes.
These days, I’m restricting directives to only elements (
The reason is that attributes are hard to compose. When multiple attribute
directives exist on one element, it can be challenging to figure out the resulting
Composability issues with attributes
Say I have these two directives that changes text colour depending on a value it observes.
Now if I add them to the same element like so, what result do I expect?
The answer is actually green because it comes after red when sorting alphabetically, so its link function is invoked last.
In this case, both directives have the default priority of
0, so according to the
official docs, their ordering is undefined. However, looking at the source code
shows us that they are indeed sorted alphabetically. Just don’t count on this
ordering in the future.
Now, I could guarantee their ordering by setting specific priority values. I don’t like this approach, because directives with a priority value forces developers to have to map out all of the directives’ interactions in their head in order to reason about them. As the number of directives grow, it becomes impossible to load everything into your head!
Composing elements instead of attributes
If I were to re-write the directives on elements instead, the result is much easier to understand.
Now, with the following HTML, can you guess what the colour is?
The answer is of course red!
Hopefully I’ve convinced you, at least a little bit, on why limiting directives to elements makes them much simpler.
In a future post, I will expand more on component patterns and how they can be applied to Angular 1 directives.