The Many Benefits of AngularJS’s ControllerAs

ControllerAs has been around for quite some time, but I hadn’t given it much thought until recently. You see, I was having issues with $parent and the isolated scopes of 3rd party directives. As if that weren’t enough, I recently read that AngularJS 2 will no longer have $scope. If you have been following AngularJS closely, you will have heard by now that they are currently developing a new major version and it is a game changer. Anyways, I needed a fix to my $parent conundrum and what I found actually has prepared me for the coming death of $scope. We will mourn our loss, dear friends, but at least we can prepare and put our affairs (and applications) slightly in order.

AngularJS’s $scope service provides us with a lot of key functionality in 1.x. You use it from binding your controllers to your views, binding/triggering events and even use it to control how Angular’s $digest cycle. So far, it has been incredibly useful…until you try to get a custom callback to function (pun intended) when someone clicks the “open” button for an Angular UI datepicker. Suddenly you run into an issue where after the user selects a date, they can no longer open the datepicker control. A typical fix? Change the datepicker popup’s isOpen attribute to use the $parent service:


<!-- Awesome fake input tag -->

<input is-open="$parent.opened" />

Problem solved, right? Wrong. You’ve just tightly coupled your datepicker popup to its parent controller’s scope, bub, and you cannot move the datepicker in that controller’s scope hierarchy without reintroducing the same issue you originally solved. Blegh. So what’s a young, resourceful web guru like yourself left to do? Use the ControllerAs functionality that is built into AngularJS 1.1.5+.

Setup your controller to use ‘this’ instead of $scope:


// Awesome controller code:

this.today = function() {
return new Date();
};

//etc...

Bootstrap your controller with an alias like ‘main’ (or something a LOT more semantic, if anyone else is ever going to read your code. Seriously, do everyone a favor. The same goes for class, function, variable and file names), and use that alias to bind to anything you exposed from the controller using the ‘this’ keyword:


<div ng-controller="mainCtrl as main">

<p>{{main.today()}}</p>

</div>

I know, that example had nothing to do with my datepicker sorrows. However, you can see how I changed Angular UI’s datepicker plunker to use the ControllerAs functionality here.

Note: You don’t have to use the ‘this’ keyword. You can instead create an object in your controller, add your properties and methods, and then return that object. The returned object then acts like your scope.

Now, you are loosely coupled and can move your datepicker anywhere within your controller’s hierarchy and can still use its functionality. Sure, you’ll see aliases everywhere, but you won’t ever deal with $parent.$parent.something ever again! In fact, you will know exactly which controller is providing what functionality! Still need to bind events or call $apply on some outside code? No worries, you can always use $scope in your controller for when you need it, rather than, well, all the time.

How does this also prepare you for AngularJS 2.0? Well, as stated before, Angular 2 will no longer have $scope. In fact, controllers are just a part of Angular’s Web Components (or Component Directive, as they are being called), where you simply define your component’s controller as a class that follows the ComponentDirective constructor. You add various class members to ‘this’, and they will be provided to the component’s view. Just like the ControllerAs functionality in 1.1.5+. All in all, ControllerAs is a simple way to attack issues with scope hierarchy as well as get yourself ready for the death of $scope.

Advertisements

One thought on “The Many Benefits of AngularJS’s ControllerAs

  1. Pingback: Markdown editor with AngularJS

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s