controllerAssyntax 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
Put all your controller properties into an object literal, and extend that object into
After that, always use
this to refer to controller properties (don’t use
A brief overview of
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.
controllerAs syntax, we get a namespace.
But then in your controller, you might have to deal with this:
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:
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
$$, 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:
However, you’ll notice that it’ll usually be better from then on to continue to refer to controller properties with
this rather than
vm, because any changes through data-binding will propogate only to
this (our namespaced controller), and not to our
vm object reference. You can leverage things like
Function.prototype.bind if you get into hairy contexts (like
forEach loops, etc.).