AngularJS's controllerAs syntax is a good first step into being able to have some sort of sense of hierarchy in applications. However, large controllers can still get unwieldy. We can move towards controlling our controllers with angular.extend .

TL;DR

Put all your controller properties into an object literal, and extend that object into this :

angular . extend ( this , vm );

After that, always use this to refer to controller properties (don’t use vm.whatever ).

A brief overview of controllerAs

Skip to the next section if you already know how to use this.

Basically, if you have a parent controller and a child controller nested within, you have to explicitly refer to $scope.$parent to access the parent controller from the child controller.

However, with controllerAs syntax, we get a namespace.

<div ng-controller= "ParentCtrl as parent" > {{parent.something}} <div ng-controller= "ChildCtrl as child" > {{child.something}} {{parent.something}} </div> </div>

But then in your controller, you might have to deal with this:

// parent.controller.js var vm = this ; vm . name = 'Bob' ; vm . job = 'Builder' ; vm . motto = 'Yes we can!' ; vm . speak = speak ; function speak () { return vm . motto ; }

Also, wondering why we’re using vm ? Check out John Papa’s AngularJS Style Guide.

Now imagine that, 1000x, when you have a controller full of lots and lots of stuff. Really, you could argue that you should consider leveraging directives and services for most of your business logic, but sometimes it’s difficult to do.

By the way, controllerAs still knows about $scope . This fake “namespace” simply happens internally by attaching an object to $scope . So in the above example, our parent controller $scope would look like this:

{ // a bunch of $$ angular properties, and then... parent : { name : 'Bob' , job : 'Builder' , motto : 'Yes we can!' , speak : function speak (){...} } }

In fact, if you were to inject $scope into that controller and ask for $scope.parent , you’d see all those properties. There’s nothing fancy about it.

Extending the view model

Ever heard of angular.extend ? It’s pretty nifty. It basically just puts properties from one object into another object, without overwriting any properties. AngularJS already attempts to protect us from this by delimiting internal properties with $ or $$ , so it’s not really a concern anyway, but it’s a nice added touch.

So, we can just make our controller look like this:

// parent.controller.js var vm = { name : 'Bob' , job : 'Builder' , motto : 'Yes we can!' , speak : speak }; angular . extend ( this , vm ); function speak () { return this . motto ; }