Subscribe via RSS Feed

Using Controllers in Angular.Js

June 16, 2014 8 Comments

What is a controller?

Controller is a JavaScript constructor function that is used to augment the Angular Scope. What does it mean? It means Controllers are essentially the entry-point into our front-end business logic. They should contain all the methods that our page should call. Controllers also allow us to initialize the scope with the models that our page uses.
Then the next question arises. Why do we need controllers?

We use controllers to:

  • Set up the initial state of the $scope object.
  •  Add behavior to the $scope object.

Now we know why should we use controllers in an angular.js application. But we have heard the word $scope so many times. But we don’t know what it is? And why should we use controllers to set up the initial state and behavior of the $scope object. So, let us get to know the $scope.

What is scope?

Scope is nothing but an object that links the View with Controller. Data in a controller is usually defined on the scope of a controller.it is also used as Angular’s two-way data binding to bind model data to view. Imagine $scope as an object that links Controller to the View. It is controllers responsibility to initialize the data that the view needs to display. This is done by making changes to $scope. So let us view a basic example to understand $scope much better.

<!DOCTYPE html>
<html ng-app>
<head>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
</head>
<body>
<h1>Basic Controller Example</h1>
<!--initiating controller-->
<div ng-controller="ContactController">
Email:<input type="text" ng-model="newcontact"/>
<button ng-click="add()">Add</button>
<h2>Contacts</h2>
<ul>
<li ng-repeat="contact in contacts"> {{ contact }} </li>
</ul>
</div>
<script type="text/javascript">
function ContactController($scope) {
//storing default value in $scope
$scope.contacts = ["[email protected]"];
$scope.add = function() {
//pushing new set of data in $scope
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
}
}
</script>
</body>
</html>

In the above example we can see that we have a input box where we can write any email address and press the add button. And that same email address will be saved temporarily in $scope.

ng-controller:

This attribute defines a Controller to be bound with the view. In this case we defined a controller called ContactController in DIV using ng-controller attribute. Thus whatever we put inside that DIV, the ContactController will have its influence on it.

There is an object $scope which we pass as an argument. This object is used to bind the controller with view. When AngularJS initialize this controller, it automatically creates and injects the $scope object to this function using dependency injection.

ng-repeat:

<li ng-repeat="contact in contacts">{{ contact }}</li>

ngRepeat is one of the most used AngularJS attribute. It iterate through an array and bind the view with each element. So in our example it creates <li> tag for each item within contacts array. ngRepeat takes expression as argument. In our case “contact in contacts” where contact is user defined variable and contacts is an array within $scope.

Creating a Controller:

This is the easiest way to create a controller, but is certainly not advisable one. Because for a large application this method can bring many complexities to the code.

function ContactController($scope) {
//...

}

To solve this problem we can define the controllers in modules. So, how can we do it?
So in this case, we can add one or more controllers to a module. Let us check the syntax to create a module and add controller to it:

var myApp = angular.module('myApp',[]);
myApp.controller('ContactController', ['$scope', function($scope) {
$scope.contacts = ["[email protected]"];
$scope.add = function() {
$scope.contacts.push($scope.contact);
$scope.contact = "";
}
}]);

In above example we created a module called myApp using angular.module() method. Then we added a controller ContactController to this module. We passed an array to this method. First argument of array is string ‘$scope’ and next is the function itself that represent ContactController. We explicitly told Angular that we have one argument (dependency) to our ContactController which is $scope. To minimize the code the argument $scope might be renamed to $s, but because we defined string ‘$scope’ as first argument, Angular is aware that first dependency to this controller is $scope object.

Setting up the initial state of $scope:

When we create an application we need to set up the initial state for the Angular $scope. We set up the initial state of a scope by attaching properties to the $scope object. The properties contain the view model . All the $scope properties will be available to the template at the point in the DOM where the Controller is registered.
The following example shows a very simple constructor function for a Controller, GreetingController, which attaches a greeting property containing the string ‘Hello!’ to the $scope:

function GreetingController($scope) {
$scope.greeting = 'Hello!';
}
Once the Controller has been attached to the DOM, the greeting property can be data-bound to the template:
<div ng-controller="GreetingController">
{{ greeting }}
</div>
We have used an inline injection annotation to explicitly specify the dependency of the Controller on the $scope service provided by Angular. See the guide on Dependency Injection for more information.

var myApp = angular.module('myApp',[]);
myApp.controller('GreetingController', ['$scope', function($scope) {
$scope.greeting = 'Hola!';
}]);

Adding Behavior to a Scope Object:

In order to react to events or execute computation in the view we must provide behavior to the scope. We add behavior to the scope by attaching methods to the $scope object. These methods are then available to be called from the template/view.
The following example uses a Controller to add a method to the scope, which doubles a number:

var myApp = angular.module('myApp',[]);

myApp.controller('DoubleController', ['$scope', function($scope) {
$scope.double = function(value) { return value * 2; };
}]);

Once the Controller has been attached to the DOM, the double method can be invoked in an Angular expression in the template:

<div ng-controller="DoubleController">
Two times <input ng-model="num"> equals {{ double(num) }}
</div>

Any objects assigned to the scope become model properties. Any methods assigned to the scope are available in the template/view, and can be invoked via angular expressions and ng event handler directives .

Nested Controllers:

We can declare the scope of controller in our HTML page using ng-controller attribute. For example:

<div ng-controller="CarController">
...
</div>

We can declare number of controllers and nest them within each other. For example:
HTML page:

<div ng-app="" ng-controller="CarController">
My name is {{ name }} and I am a {{ type }}

<div ng-controller="BMWController">
My name is {{ name }} and I have a {{ type }}

<div ng-controller="BMWMotorcycleController">
My name is {{ name }} and I live in {{ place }}

</div>
</div>
</div>

JAVASCRIPT page

function CarController($scope) {

$scope.name = 'John';
$scope.type = 'Developer';

}

function BMWController($scope) {

$scope.type = 'BMW car';

}

function BMWMotorcycleController($scope) {

$scope.name = 'John';
$scope.place = 'California';

}

controller

In above demo, notice how each nested Controller’s scope override the scope of parents controller. First we defined a controller CarController which defines two variables name and type within scope. Next BMWController is nested within CarController using ng-controller attribute. BMWController overrides type attribute and change it to BMW. It does not change name attribute so name attribute is still John.

BMWMotorcycleController is the inner-most controller defined within controllers hierarchy. It overrides both name and type attribute of scope.

Related Links:
1>Directive in Angular.js – Part 1
2>Directive in Angular.js – Part 2
3>Working with Modules in Angular.js
4>Angular Router and UI-Router
5>Angularjs and Services
6>Angular.js Promise
7>Angular.js Two Way Data Binding
8>How To Use Filter In Angular.js
9>Angular.js Event Handling
10>Angularjs with Server Side Interaction
11>Working Through Angular.js With Transclude
12>Angular Templates

If you find this article helpful, you can connect us in Google+ and Twitter.