Thursday, 12 November 2015

Angular JS - Controllers

Understanding Controllers

A Controller is defined by a JavaScript constructor function that is used to augment the Angular Scope.
When a Controller is attached to the DOM via the ng-controller directive, Angular will instantiate a new Controller object, using the specified Controller's constructor function. A new child scope will be created and made available as an injectable parameter to the Controller's constructor function as $scope.

In general, a Controller shouldn't try to do too much. It should contain only the business logic needed for a single view.The most common way to keep Controllers slim is by encapsulating work that doesn't belong to controllers into services and then using these services in Controllers via dependency injection. We can associate Controllers with scope objects implicitly via the ngController directive or $route service.

If the controller has been attached using the controller as syntax then the controller instance will be assigned to a property on the new scope.

Use Controllers TO:
  • Set up the initial state of the $scope object.
  • Add behavior to the $scope object.

Do not use Controllers To: 
  • Manipulate DOM — Controllers should contain only business logic. Putting any presentation logic into Controllers significantly affects its testability. Angular has databinding for most cases and directives to encapsulate manual DOM manipulation.
  • Format input — Use angular form controls instead.
  • Filter output — Use angular filters instead.
  • Share code or state across controllers — Use angular services instead.
  • Manage the life-cycle of other components (for example, to create service instances).

Initial State of $scope Object - 
The following example demonstrates creating a MessageController, which attaches a message property containing the string 'Hello Krishna!' to the $scope:

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

myApp.controller('MessageController', ['$scope', function($scope) {
  $scope.message= 'Hello Krishna!';
}]);
 
We create an Angular Module, myApp, for our application. Then we add the controller's constructor function to the module using the .controller() method. This keeps the controller's constructor function out of the global scope.

We attach our controller to the DOM using the ng-controller directive. The message property can now be data-bound to the template:

<div ng-controller="MessageController">
  {{ message}}
</div>

 NOTE: We have used an inline injection annotation to explicitly specify the dependency of the Controller on the $scope service provided by Angular.

Simple Spicy Controller Example

The message in our template contains a binding to the spice model which, by default, is set to the string "very". Depending on which button is clicked, the spice model is set to chili or jalapeño, and the message is automatically updated by data-binding.

Create one HTML page and replace <head> and <body>
Create one js file of named app.js at the same location



HTML
<head>
  <meta charset="UTF-8">
  <title>Example - 1</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
  <script src="app.js"></script>
</head>
<body ng-app="spicyApp1">
  <div ng-controller="SpicyController">
 <button ng-click="chiliSpicy()">Chili</button>
 <button ng-click="jalapenoSpicy()">Jalapeño</button>
 <p>The food is {{spice}} spicy!</p>
</div>
</body>

JS
var myApp = angular.module('spicyApp1', []);
myApp.controller('SpicyController', ['$scope', function($scope) {
    $scope.spice = 'very';

    $scope.chiliSpicy = function() {
        $scope.spice = 'chili';
    };

    $scope.jalapenoSpicy = function() {
        $scope.spice = 'jalapeño';
    };
}]);


Things to notice in the example above:
  • The ng-controller directive is used to (implicitly) create a scope for our template, and the scope is managed by the SpicyController Controller.
  • SpicyController is just a plain JavaScript function. As an (optional) naming convention the name starts with capital letter and ends with "Controller".
  • Assigning a property to $scope creates or updates the model.
  • Controller methods can be created through direct assignment to scope 
  • The Controller methods and properties are available in the template (for both the <div> element and its children).
Spicy Arguments Controller Example -
Controller methods can also take arguments, as demonstrated in below example

HTML
<div ng-controller="SpicyController">
 <input ng-model="customSpice">
 <button ng-click="spicy('chili')">Chili</button>
 <button ng-click="spicy(customSpice)">Custom spice</button>
 <p>The food is {{spice}} spicy!</p>
</div>

JShttps://www.blogger.com/blogger.g?blogID=7975656151796446109#editor/target=post;postID=5935261620062027429;onPublishedMenu=allposts;onClosedMenu=allposts;postNum=0;src=postname
var myApp = angular.module('spicyApp2', []);
myApp.controller('SpicyController', ['$scope', function($scope) {
    $scope.customSpice = "wasabi";
    $scope.spice = 'very';

    $scope.spicy = function(spice) {
        $scope.spice = spice;
    };
}]);

NOTE: SpicyController Controller now defines just one method called spicy, which takes one argument called spice. The template then refers to this Controller method and passes in a string constant 'chili' in the binding for the first button and a model property customSpice (bound to an input box) in the second button.


Scope Inheritance Controller Example 
Since the ng-controller directive creates a new child scope, we get a hierarchy of scopes that inherit from each other. The $scope that each Controller receives will have access to properties and methods defined by Controllers higher up the hierarchy. See Understanding Scopes for more information about scope inheritance.


 HTML
<div class="spicy">
  <div ng-controller="MainController">
    <p>Good {{timeOfDay}}, {{name}}!</p>

    <div ng-controller="ChildController">
      <p>Good {{timeOfDay}}, {{name}}!</p>

      <div ng-controller="GrandChildController">
        <p>Good {{timeOfDay}}, {{name}}!</p>
      </div>
    </div>
  </div>
</div>


JS
var myApp = angular.module('scopeInheritance', []);
myApp.controller('MainController', ['$scope', function($scope) {
  $scope.timeOfDay = 'morning';
  $scope.name = 'Nikki';
}]);
myApp.controller('ChildController', ['$scope', function($scope) {
  $scope.name = 'Mattie';
}]);
myApp.controller('GrandChildController', ['$scope', function($scope) {
  $scope.timeOfDay = 'evening';
  $scope.name = 'Gingerbread Baby';
}]);


 CSS
div.spicy div {
  padding: 10px;
  border: solid 2px blue;
}

Notice how we nested three ng-controller directives in our template. This will result in four scopes being created for our view:
  • The root scope
  • The MainController scope, which contains timeOfDay and name properties
  • The ChildController scope, which inherits the timeOfDay property but overrides (hides) the name property from the previous
  • The GrandChildController scope, which overrides (hides) both the timeOfDay property defined in MainController and the name property defined in ChildController
Inheritance works with methods in the same way as it does with properties. So in our previous examples, all of the properties could be replaced with methods that return string values.

No comments:

Post a Comment

Monads in Scala

Monads belongs to Advance Scala   concepts. It  is not a class or a trait; it is a concept. It is an object which covers other object. A Mon...