Starting with version 1.5, AngularJS supports a special directive type called component.
You should start using them today! Let’s see how!
The idea of web components and custom HTML tags has been around for a while. Using them in our apps can lead to a better organization and a clear separation of concerns.
In this article we will write a simple todo list using the new component syntax. Bear with me!
Components are just directives, but having a configuration slightly smaller than the usual.
First of all, they are directives that have the
restrict option set to E. That means only element directives are allowed.
The second change is the declaration of scope bindings. Instead of having a
bindToController option set to
true and a
scope option with our bindings, we will use only a
bindings option. The
controllerAs default value is $ctrl.
terminal options are not allowed, and scopes are always isolated.
Another small difference is the a binding signal,
<, that means one-way binding. Effectively, this is a watcher on outer scope that keeps a local property on controller in sync, but won’t change the outer scope if we modify it locally. So the bindings is always from outer to inner scope.
- components always have a controller
- $ctrl is the default alias
- components are directives of type
elementonly. No more classes, attributes or comments!
scopeto inject values from the outside world in the component
- use the
$onInitmethod on component class to initialize local bindings and component state, instead of doing that on constructor
When you should NOT use components:
- If you need a directive that adds behaviour to a node, like
- If your directive needs to manipulate the DOM using
- If you need control of the execution order through
- If you need to process an attribute rather than an element
Another important thing that you should keep in mind is that now the
require option is used as a mapping between directive controllers and properties. For example, if you have to write a custom input element and you need to use
ngModel along with your directive, here’s how the
require option will look like:
The config above is telling Angular to require the “ngModel” directive’s controller and assign it to a property called “model” in our controller.
A very important thing to remember is that the directives may not be available when the component’s controller is instantiated, but is guaranteed that they are available on
The syntax is very similar to a directive, with one main difference: instead of writing an injectable function to declare the directive, use an object.
Here’s an example of a component:
As you can see, our component will receive the list of tasks through the
list attribute and fire a click handler defined on
The new component will be used in the app as a custom tag. Assuming
app is our main app controller, this is how it looks:
<todo-list list="app.list" on-task-click="app.markAsDone(task)"></todo-list>
Our component also needs some styles to render the tasks so let’s add some!
Ideally, our entire application should be a tree made out of small and focused components.
So let’s also create a component for our app!
And that’s it! Let’s see our component in action: