This post was originally published on Mar 29, 2016 but has been updated to reflect the latest information.
Angular 1.5 has been finally released and it’s more powerful than ever before! Many new features have been added and tons of fixes landed in the latest bigger release. If you’re following our articles, you know that we love to give an overview of the latest and greatest in the Angular world. Last year we blogged about the 1.3 release in our article series Exploring Angular 1.3. With this article we’re going to start a new series called, guess what, “Exploring Angular 1.5”, and the first topic we’re going to explore is the new feature of Lifecycle Hooks. Let’s get started right away!
Lifecycle hooks in Angular landed first in the Angular 2 alpha release and they are more or less inspired by the Custom Elements lifecycle callbacks. By inspired we mean that they are not exactly the same. They’re not only named differently and do different things, there are also more. An Angular 2 component comes with lifecycle hooks like
ngOnChanges() and many more. We get a very detailed overview of these in the official docs.
However, this article is on Angular 1.5. Since Angular 1 is evolving in a way to keep the gap to Angular 2 as small as possible, some lifecycle callbacks have been backported to the current “best Angular yet”. Let’s take a look at them one by one.
Note: The Angular lifecycle-hooks were introduced in version 1.5.3.
This lifecycle hook will be executed when all controllers on an element have been constructed and after their bindings are initialized. This hook is meant to be used for any kind of initialization work of a controller. To get a better idea of how this behaves, let’s take a look at some code.
We start off with an Angular 1.5 component
myCmp. A component has a controller and a template, and in our example, our component simply has a
name property that we interpolate.
$ctrl is the default
controllerAs namespace, which is super nice because we don’t have to set it up.
We can now move the initialization work into the
$onInit lifecycle hook, by defining the hook on the controller instance:
Okay great. But uhm… what’s the big deal? Well, while the resulting output will be the same, we now have the nice side effect that this component doesn’t do any initialization work when its constructor is called. Imagine we’d need to do some http requests during initialization of this component or controller. We’d need to take care of mocking these requests whenever we construct such a component. Now we have a better place for these kind of things.
Another nice thing about
$onInit, is that we can access controllers of parent components on our own component’s controller, as those are exposed to it for intercomponent communication. This means it’s not even necessary anymore to have a
link() function to access other directive controllers.
For example, if we’d build a
<tabs> component and a
<tab> component, where the latter needs access to the
TabsController to register itself on it, we can simply ask for it using the
require property an call it directly via the controller instance.
So after all, this aligns perfectly with what we’ve predicted a long time ago in our article on binding to directive controllers.
This hook allows us to react to changes of one-way bindings of a component. One-way bindings have also been introduced in Angular 1.5 and align a bit more with Angular 2’s uni-directional data flow. Let’s say we make the
name property of our
myCmp configurable from the outside world using a one-way binding:
We can now bind an expression to the component’s
name property like this:
Let’s say we want to prepend the name with “Howdy” when the name is “Pascal” and otherwise simply greet with “Hello”. We can do that using the
$onChanges() lifecycle hook. It gets called with an object that holds the changes of all one-way bindings with the
currentValue and the
$onDestroy() is a hook that is called when its containing scope is destroyed. We can use this hook to release external resources, watches and event handlers.
For example, if we’d manually set up a
click handler (instead of using
ng-click), we need unregister the event handler when the component is destroyed, otherwise it’ll keep hanging around and leaks memory.
There has been a lot of discussion around the fact that
bindToController pushes us into the direction not to use
link() anymore, and rather stick to simply
controller() because it does the same job almost all the time, because it seemed unclear what to do when DOM manipulation needs to be done.
Well, it turns out there has always been the local injectable
$element, which is basically a reference to the DOM element on which our directive is applied. This reference can and could be used to do DOM manipulation, even in the controller.
This still gave some Angular users a weird feeling because there’s this one rule to not do DOM manipulations in the controller. This rule still applies, unless we’re talking about directive controllers. And a component controller is a directive controller.
In Angular 1.5 it gets even better, because there’s a lifecycle hook called
$postLink(), which not only can be the place where we do all of the DOM manipulation, but it’s also the hook where we know that all child directives have been compiled and linked.
We’ll see if there are going to be more lifecycle hooks that Angular 1.5 can take advantage of. We clearly can’t simply backport all of Angular 2’s lifecycle hooks, because the compilation process is not exactly the same, so some lifecycle hooks don’t really make sense in an Angular 1 world.
Sponsoring AngularConnect. Again.
Today we are very happy to announce that we're going to sponsor AngularConnect - again! We're also going to run...
ngMessageFormat - Angular's unheard feature
Angular 1.5 is pretty much around the corner. It turns out that there's a feature that already landed in Angular...
Multiple Transclusion and named Slots
One of those bigger features in the 1.5 release is multiple transclusion via named slots. In this article we're going...
Service vs Factory - Once and for all
This is yet another article on services vs factories in AngularJS. It explains once and for all, why we mostly...
Taking Angular Master Class to the next level
We always collect feedback to make our material and trainings even better. We listened. Here's what we did.
With the release of Angular 1.4, a few changes landed that affect the ngMessages module. This article discusses what has...