Angularjs

AngularJS Controllers

Controllers are an intermediate channel between View and Model.It is preferred to have multiple controllers to control different views of a page to make debugging and maintainability easy.To use any controller for a view first, that should be defined and registered with the application module.

Controllers are created using Javascript’s Constructor Function. Therefore whenever Controller is attached to the DOM new controller object will be instantiated and a new child $scope will be created to initialize the state and to add behaviors to the DOM elements.

Example:

index.html

<!DOCTYPE html>
<html>
<head>
<title>Angular JS Controllers</title>
<script src="main.js"</script>
</head>
<body ng-app="mainApp" ng-controller="mainController">
{{message}}
</body>
</html>

main.js

var app=angular.module("mainApp",[]);
var controller = app.controller("mainController",['$scope',function($scope){
$scope.message = "Hello Controller!!"
}]);

TRY IT!!

Here if we observe the controller definition “mainController” is the controller name and defined the constructor function in controller() method.Initialized the $scope property “message”.

Controller is attached on <body></body> element.Hence properties initialized in the controller can be used in DOM.Here we are displaying the property using expression(“{{}}“).

NOTE: If we observe the above example we passed the second argument as an array.During the minification process, Javascript tools minify the variables here $scope will be minified to $s then there is no idea for the controller what this variable $s refer to.To avoid these problems we’ll pass the function parameters as strings in the same order they are passed in function definition in an array before the function.

Controller as

Controllers can also be attached to the DOM using the controller as syntax to access the controller’s properties.Using this approach would mean that the controller can define properties without required to push those on the $scope.

Example:

index.html

<!DOCTYPE html>
<html>
<head>
<title>Angular JS Controllers</title>
<script src="main.js"</script>
</head>
<body ng-app="mainApp" style="background-color:black" ng-controller="mainController as ctrl">
<div style="text-align:center;color:orange;background-color:#ffffff;font-size:20px;margin-top:30%">{{ctrl.message}}</div>
</body>
</html>

 main.js

var app = angular.module("mainApp",[]);
var controller = app.controller("mainController",function(){
this.message = "Controller with 'Controller as' functionality!!"
});

TRY IT!!

Here we have not passed any $scope parameter to function definition instead used this to set the properties.

Communication between controllers

There are times when one controller needs to communicate with other controllers.For Example, a user needs the other components of the view to be aware of changes done by one controller.There are many ways to achieve the same.Let’s see one by one in detail.

Making Function Global

Let’s create a simple markup with two divs each associated with a different controller.By clicking a button in one div will update the value in other div.

index.html

<!DOCTYPE html>
<html>
<head>
<title>Controller Communication</title>
<script src="app.js" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js" />
</head>
<body ng-app="myApp" style="text-align:center">
  <h4 style="background-color:black;color:white;padding-top:5%;padding-bottom:5%;">
    Controller communication using global function
  </h4>
  <div style="border:solid 2px black;margin-top:-3%;padding-top:5%;padding-bottom:5%">   
  <input type="text" ng-controller="ctrl1" style="background-color:red;color:white;text-align:center" ng-       model="number" />   
  <span ng-controller="ctrl2">
    <input type="button" value="Increment-Count" ng-click="IncrCount()" />
  </span>
  </div>
</body>
</html>

app.js

var app = angular.module("myApp", []);
app.controller("ctrl2", ["$rootScope", "$scope", function($rootScope, $scope) {
  $scope.IncrCount = function() {
    $rootScope.incCount(++$rootScope.number);
  };
}]);
app.controller("ctrl1", ["$rootScope", "$scope", function($rootScope, $scope) {
  $rootScope.number = 0;
  $rootScope.incCount = function(count) {
    $rootScope.number = count;
  }
}]);

Here whenever we click on Increment-Count button the value in input text box changing. This is possible by incrementing the value of the div controlled by ctrl1 by another controller i.e, ctrl2.This is achieved only by declaring the ctrl1 function as global i.e, on $rootScope.

Try It!!

Using Factory Services

This is the most commonly used method to share data between controllers.Here controllers communicate with the service(factory) to get the updated data.

index.html

<!DOCTYPE html>
<html>
<head>
<title>Communication using factory</title>
<script src="app.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
</head>
<body ng-app="myApp" style="text-align:center">
  <h4 style="background-color:black;color:white;padding-top:5%;padding-bottom:5%;">
Controller communication using global function
</h4>
  <div style="border:solid 2px black;margin-top:-3%;padding-top:5%;padding-bottom:5%">
    <input type="text" ng-controller="ctrl2" style="background-color:red;color:white;text-align:center" ng-model="textbox1">
    <input type="text" ng-controller="ctrl1" style="background-color:red;color:white;text-align:center" ng-model="textbox2">
  </div>
</body>
</html>

app.js

var app = angular.module("myApp", []);
app.controller("ctrl2", ["communicatorService", "$scope", function(communicatorService, $scope) {
  console.log(communicatorService.text);
  $scope.textbox1 = communicatorService.text;
  communicatorService.text = "Hiii!!!";
}]);
app.controller("ctrl1", ["communicatorService", "$scope", function(communicatorService, $scope) {
  console.log(communicatorService.text);
  $scope.textbox2 = communicatorService.text;
}]);

app.service("communicatorService", function() {
  this.text = "Hello!!!";
  return this;
});

Here the ctrl1 input box text field is set in ctrl2 using factory as soon it is set it will be reflected in ctrl1 input box text field.

Try It!!

Using Broadcast and On Events 

Here these events are available on rootScoop implies these are application-wide events. The broadcast event is fired on some event in one controller and the event will be captured by the all the listening controllers when it is triggered through on the event.

index.html

<!DOCTYPE html>
<html>
<head>
<title>Controller communication using Broadcast and On events</title>
<script src="app.js" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js" />
</head>
<body ng-app="myApp" style="text-align:center">
  <h4 style="background-color:black;color:white;padding-top:5%;padding-bottom:5%;">
Controller communication using global function
</h4>
  <div style="border:solid 2px black;margin-top:-3%;padding-top:5%;padding-bottom:5%">
    <input type="text" ng-controller="ctrl1" style="background-color:red;color:white;text-align:center" ng-model="number" />
    <span ng-controller="ctrl2">
    <input type="button" value="Increment-Count" ng-click="IncrCount()"  />
  </span>
  </div>
</body>
</html>

app.js

var app = angular.module("myApp", []);
app.controller("ctrl2", ["$rootScope", "$scope", function($rootScope, $scope) {
  $scope.IncrCount = function() {
    $rootScope.$broadcast("buttonClicked");
  };
}]);
app.controller("ctrl1", ["$rootScope", "$scope", function($rootScope, $scope) {
  $scope.number = 0;
  $rootScope.$on("buttonClicked", function() {
    $scope.number = $scope.number + 1;
  });
}]);

Here an event named buttonClicked is fired in ctrl2 through a broadcast event and it is received in ctrl1 via on event and incrementing the count of a number whenever the button is clicked and updating the number in another view.

Try It!!

Using $watch handler

Watch is used to watch the data registered on the scope variable.We can use it in controllers communication by registering the variables on rootScope in one controller and watching the same data in another controller and updating the view by changed data.

index.html

<!DOCTYPE html>
<html>
<head>
<title>Controllers communication using $watch</title>
<script src="index.html"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"/>
</head>
<body ng-app="myApp" style="text-align:center">
  <h4 style="background-color:black;color:white;padding-top:5%;padding-bottom:5%;">
Controller communication using watch events
</h4>
  <div style="border:solid 2px black;margin-top:-3%;padding-top:5%;padding-bottom:5%">
    <input type="text" ng-controller="ctrl1" style="background-color:red;color:white;text-align:center" ng-model="number" />
    <span ng-controller="ctrl2">
    <input type="button" value="Increment-Count" ng-click="IncrCount()"  />
  </span>
  </div>
</body>
</html>

app.js

var app = angular.module("myApp", []);
app.controller("ctrl2", ["$rootScope", "$scope", function($rootScope, $scope) {
  $rootScope.count = 0;
  $scope.IncrCount = function() {
    $rootScope.count =  $rootScope.count +1; 
  };
}]);
app.controller("ctrl1", ["$rootScope", "$scope", function($rootScope, $scope) {
  $scope.number = 0;
  $rootScope.$watch("count", function() {
    $scope.number =  $rootScope.count;
  });
}]);

Try It!!

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *