With the creation of AngularPrime, I learned a lot of the directives feature of AngularJS. And it is one of the things that I like about the framework. You are able to create tags that define your custom functionality or create a reusable series of codes. And since I'm coming from the JSF world, the custom component functionality is something I like and use very much.
So in this series of small blog items, I'll walk through the learning path of writing directives. Writing them can be confusing sometimes because you have many options and knowing what to use is not always obvious.
At the end of the series, we will have a directive that is capable of showing a panel.
Panel directiveSo, for this series of blog items, we will set the target that we need to create a panel, a grouping element, that has a title and optionally an icon to collapse and expand the panel contents.
In our page we like to have something like this
<div my-panel title="Panel title">Panel contents</div>
The end result could look something like
This is the complete requirements lists
- Attribute title specifies the panel title but can contain AngularJS expressions
- The contents can consist of any html tag, including angularJS expressions and other directives, from AngularJS or custom defined.
- The need for an icon to expand/collapse the panel content can be configured in the my-panel attribute/directive.
- Configuration of the expand/collapse functionality can be in HTML or within a Scope object.
- Allow the programmatic expand/collapse of the panel contents.
Compile/linkWhen you create custom directives, you need to know a few basic principles of the AngularJS compiler. It is responsible for looking at the HTML code and setting up the 2 way data binding. This is the magic thing so that you no longer need to do DOM manipulations.
The AngularJS compiler works in 2 phases. In the first phase, a bit confusing, called compile, it scans the HTML for all directives. It prepares the elements as template that are combined with the model data from the scope in the link phase.
The combination of the template and the data is performed in the link phase. If you look at the ngRepeat directive you can understand the reason for this separation.
In the compile phase, there is a template created that is used as many times as needed (as the number of items in the list) in the link phase. If the number of items changes later on, the template can be reused. This way, template creation is only performed once.
So there are a few things that you need to remember if you write a directive
- You only have access to the scope values in the link phase, not the compile phase.
- When your directive should change the DOM structure, you need to make your changes in the compile function (linked to the compile phase)
- When there are only functional behaviour (responding to events) and styling changes, you can use the link function as no DOM structure changes are required.
- If you need DOM structure changes and need access to the scope values, you need a special construct that Il'l show you later on in some of the blog items.
So, now we are ready for learning creating our own directives.