Migrating to Angular 1.2: Modular Routing, Animations, ng-If, et al.

Note that Angular 1.2 is not yet officially released. They’re currently at Release Candidate 3, which you can install via direct download of the ‘unstable’ release at Angularjs.org, or with:

bower install angular#1.2.0-rc.3

There’s no official migration guide available as yet. So, I’m assembling bits and pieces from my own experience and from posts by others. Bottom line: many big changes in Angular are incremental and break nothing. But other changes are pretty substantial and will require modifications of your existing code to even get your app up and running. 

New Components, like ‘angular-route’

The first thing you’ll notice is that Angular has been broken down into additional component parts, each of which needs to be loaded as a separate file, and listed as a dependency of your main app module. Think this applies only to secondary constructs, like $http or something? No; try routing.

Just to get an application up and running with simple routing, you’ll now need to manually add the ngRoute module as a dependency, just as you perhaps did before if you used angular-resource, angular-cookies, etc. (Ostensibly, the new components will be standard options in Yeoman’s Angular generator(s), once the final release is out.) So, in addition to loading the angular-route.js file one way or another, you’ll include the dependency declaration in the creation of your main app module like so:

angular.module('myApp', ['ngRoute', 'otherDependency']).config() ...

That’s the biggest change you’ll need to deal with immediately, in order to adapt an Angular 1.0.x application. The other big changes are whole new features.

Animations

In a nutshell, Angular’s animations support is designed to allow you to animate elements as they enter and exit the page, via an ng-repeat, ng-view,  ng-include, ng-switch or ng-if. (ng-if is new and good! More below.) Animations can also be triggered on activation of an ng-show, ng-hide, or ng-class directive. Animations are also in a separate module you’ll need to activate as a dependency.

The great thing here is that your animations can all be defined with standard CSS. You can use transitions or keyframe animation, and author your animations with external tools like Greensock or Adobe Edge Animate. There’s no new API or procedure to learn, except for adding some special class names to your standard CSS blocks. Those class names will be applied to elements by Angular during the various phases of the animation. (Note that earlier unstable versions of the ngAnimate API from the 1.1.x branch relied on directive invocation on elements you wanted to animate. This is no longer valid, so be careful when reading about it, and make sure that you’re reading materials that reference version 1.2.)

“But what if I have to support ancient versions of Internet Exploder?!?”, you ask? No CSS animation support there! You’re in luck: an option for javascript animation functions is also provided: allowing you to rely on optimized CSS animations when possible, and smoothly fall back to JS when necessary.

For additional learning about ngAnimate, read the excellent interpretive article by Angular team member and ngAnimate principal author Matias Niemelä (aka, ‘yearOfMoo’), Animation in AngularJS 1.2; then, learn about Core concepts in the Angular Developer Guide, and see the ngAnimate API.

ng-If

My first assumption about new directive ng-If was that it was just an API replacement for ng-Show and ng-Hide. Not so! According to the docs:

ngIf differs from ngShow and ngHide in that ngIf completely removes and recreates the element in the DOM rather than changing its visibility via the display css property. A common case when this difference is significant is when using css selectors that rely on an element’s position within the DOM, such as the :first-child or :last-child pseudo-classes.

It’s also hugely significant in that any expressions you have in that hunk of DOM aren’t firing even when the HTML fragment is inactive, as with partials included via show/hide. Because it’s not actually there.  This can provide performance advantages, and prevents you from needing to write expressions that will always be valid, even though the state of your model may have significant changes that will happen before that hunk of DOM is ever rendered. Notably, I’ve just realized (I think) that this behavior is the same as ngSwitch. Until now, I had thought that ngSwitch was to ngShow as a javascript switch block is to an if…else block. But ngSwitch turns out to add and remove the content, not merely show and hide it. ngIf appears to be different, simpler syntax for the same general idea, minus an ngSwitch-ed element’s ability to contain additional, nonconditional content. See this CodePen for a demo, which includes all three directives.

I find this kind of approach very useful when you need something that’s halfway between full routing and mere show/hide, such as when you want to make wholesale view changes, but without allowing the user to deep-link to those various states of the view. I’ll use this a lot for situations like games, where you want a complete page/view-content swap, but you don’t want someone to be able to start in the middle of a progression. You could do that with ngShow, but then you’ve got all of your expressions evaluating on the hidden content.

Notes: you can maximize performance any time you’re swapping templates in and out (including with routing) by taking advantage of $templateCache. This’ll get the UX of ng-switch & ng-if closer to that of ng-show. ng-if also supports ng-animate for effects when partials are inserted or detached.

Improved Docs!

In addition to new features, we’re also getting some freshly overhauled documentation to go with them. The Developer Guide on Directives, in particular, has gotten a lot of love.

And More…

One of the very few articles out there covering new features is at neevtech.com. That piece mentions two new directives that provide us with ways to easily respond to blur and focus events, a new directive for swipes, and some additions to ng-repeat that allow us to key off of $even or $odd index numbers, rather than just first, last and middle. Last, it also talks about making ‘JQuery’ available outside of Angular scope, but I’m not sure how cogent/accurate that claim is. They may possibly mean that angular.element/jqlite is now available from outside of Angular scope, but that appears to have been the case since the 1.0.x branch, so I’m just not sure.

As more information comes in about the 1.2 release, I’ll update this post. But for now, this covers the biggest changes I’m aware of. Several folks in my shop have been using the release candidates (and even the 1.1.x branch) for a while now, and report good outcomes. May that experience extend to you, dear reader, as well.

Leave a comment