Forward Advance Learning

Controllers

AngularJS, as originally designed gave us an MVC pattern. MVC looks like this:

  • Model - our data, typically JSON objects.
  • View - the template - HTML5.
  • Controller - a JavaScript object that mediates between the two.

So far, we have only dealt with the view (the HTML5). In this section we will start to look at controllers, and how we can use them to mediate between our view and our data.

Creating a controller

We initialise a controller by chaining .controller onto our module definition. The .controller function receives a string, which is the name of our controller, and a constructor function, which will be used to build the controller.

A controller looks something like this:

angular.module('app', [])
.controller("DemoController", function($scope) {
$scope.hello = "World";
});

We hook this into our template something like this:

<div ng-app="app" ng-controller="DemoController">
{{hello}}
</div>

$scope

Notice that the controller constructor receives a parameter called $scope.

$scope is a special object managed by Angular that is shared between the controller and the template. We use it to pass data abck and forth. All our data (models) are stored in $scope. We can also store helper functions here.

The purpose of the controller is to create models and helper functions for the view

I'll say again: The purpose of the controller is to create models and helper functions for the view. Not to do AJAX (we use services for this). Not to make DOM changes (we use Directives for this). If you find your controller getting large and trying to manage too much, you probably need to reconsider. We'll look more at this later in the course.

Adding Helper Methods to a Controller

We can store helper methods on our controller, those will be available in the front end:

angular.module('app', [])
.controller("DemoController", function($scope) {
$scope.sayHello = function() {
$scope.greeting = "Hello"!
};
});

If we have Babel, or are targetting only evergreen browsers, we can use the ES6 fat arrow syntax like so:

angular.module('app', [])
.controller("DemoController", function($scope) {
$scope.sayHello = () => $scope.greeting = "Hello"!
});

We hook this into our template something like this:

<div ng-app="app" ng-controller="DemoController">
<a ng-click="sayHello()">Say Hello</a>
{{greeting}}
</div>

When to create a controller

I generally expect to create one controller per unit of interaction (later per-component). This means we typically create quite a lot of controllers. For example, you might have a loginFormController, a profileController, a signupController, etc. Many small controllers are better than one massive multi-purpose monolith. A medium sized app might have dozens or even hundreds of controllers.

Controller scope

A controller will apply to an html5 element and all of it's children. We can nest controllers inside each other, in which case the child controller takes precedence if there is a conflict. This is decided using prototypical inheritance. More on this when we get to the section on $scope.

Some of you might be yelling "What about controller-as!" right about now. We'll get to that shortly.

Exercise - Control yourself

We are going to add a profileController to your super advanced profile form from the previous exercise.

  1. Create a profileController. Use ng-controller to add it to your profile form.
  2. In your controller, set a default name, description and profile picture URL.

Exercise - Helper function

Extend the calculator exercise. We are going to create a function to allow us to zero all the values.

  1. Create a function in your controller which zeros number1 and number2. Add it to $scope. It is now available in your front end.
  2. Add a button to your DOM and use ng-click to call the function.

Remember you never need to refer to $scope in your template. $scope is always implied.

Further Reading

Read the controller guide here: https://docs.angularjs.org/guide/controller