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
$scopeobject. - Add behavior to the
$scopeobject.
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
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>
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';
};
}]);
Controller methods can also take arguments, as demonstrated in below example
HTML
JShttps://www.blogger.com/blogger.g?blogID=7975656151796446109#editor/target=post;postID=5935261620062027429;onPublishedMenu=allposts;onClosedMenu=allposts;postNum=0;src=postname
NOTE:
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
HTML
JS
CSS
<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-controllerdirective is used to (implicitly) create a scope for our template, and the scope is managed by theSpicyControllerController. SpicyControlleris just a plain JavaScript function. As an (optional) naming convention the name starts with capital letter and ends with "Controller".- Assigning a property to
$scopecreates 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).
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
MainControllerscope, which containstimeOfDayandnameproperties - The
ChildControllerscope, which inherits thetimeOfDayproperty but overrides (hides) thenameproperty from the previous - The
GrandChildControllerscope, which overrides (hides) both thetimeOfDayproperty defined inMainControllerand thenameproperty defined inChildController
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