Introduction
There are scenarios that occur when we need to use all fields/methods of one of the already defined controllers in a new controller and also define our own methods.
We can also override the methods of parent controller and provide our own implementation just like inheritance.
We are also going to see how to avoid $scope
injection in controller and avoid to fire respective associated watchers function which results in performance gain.
Using the Code
First, we created our first controller.
var app = angular.module('inheritanceDemo', []);
app.controller('MainCtrl', function() {
this.dad = 'Dad';
this.mom = 'Mom';
this.methodclick=function(){
alert('I am Dad/Mom');
}
});
Here, we have not injected $scope
in our controller. Instead of that, we are using "this
" object to bind fields and methods for the respective controller.
Yes! It will also do the same job as $scope
does and also follow the two way data binding feature. That also, we are going to see ...
While crating the child controller, we will have to use $controller
service.
We will need to inject $controller
service to instantiate a controller inside child controller.
$controller
service is responsible for instantiating controllers.
app.controller('ChildCtrl', function($controller) {
var ChildCtrl=this;
ChildCtrl.child = $controller('MainCtrl',{});
ChildCtrl.child.Name="Puppy"
});
Here, I have created the child controller and initialised the ChildCtrl
which will hold the reference of "this
" object.
So now, the parent controller instance is assigned to child controller using $controller
.
ChildCtrl.child = $controller('MainCtrl',{});
Here, child
is property defined on ChildCtrl
which is a reference of "this
" object.
New field "Name
" is also defined on this child
property which would be specific for ChildCtrl
only.
Forget about the methodclick
and methodclick1
methods for now. So those are commented now.
Below is the code snippet for HTML. Here, we have used controller as alias.
<div style="border:1px;solid;border-color:Red;"
ng-controller="MainCtrl as parent">
<p>Hello {{parent.dad}}!</p>
<p>Hello {{parent.mom}}!</p>
<span ng-click=parent.methodclick()>Parent Click </span>
</div>
<div ng-controller="ChildCtrl as Children">
<p>Hello {{Children.child.dad}}!</p>
<p>Hello {{Children.child.mom}}!</p>
<span ng-click=Children.child.methodclick()>Child Click </span>
Here, you can observe that child controller has inherited all fields and methods from its parent controller.
If you run the code and click on child click span parent method will call.
You can override it by your own implementation.
Just uncomment the method methodclick
in child controller and run code again. Now, child method will call on click of Client
click method.
If you want to test two way data binding for "this
" object which we have used, just add the below HTML in your HTML code.
<input ng-model="Children.child.Name" />
<span >{{Children.child.Name}}</span>
Below is the full code snippet:
JS
var app = angular.module('inheritanceDemo', []);
app.controller('MainCtrl', function() {
this.dad = 'Dad';
this.mom = 'Mom';
this.methodclick=function(){
alert('I am Parents')
}
});
app.controller('ChildCtrl', function($controller) {
var ChildCtrl=this;
ChildCtrl.child = $controller('MainCtrl',{});
ChildCtrl.child.Name="Puppy"
ChildCtrl.child.methodclick=function(){
alert('I am their child');
}
ChildCtrl.child.methodclick1=function(){
alert('We are separate');
ChildCtrl.child.Name="We r free";
}
});
HTML
<!DOCTYPE html>
<html ng-app="inheritanceDemo">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' +
document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.3.x"
src="https://code.angularjs.org/1.3.6/angular.js"
data-semver="1.3.6"></script>
<script src="app.js"></script>
</head>
<body >
<div style="border:1px;solid;border-color:Red;"
ng-controller="MainCtrl as parent">
<p>Hello {{parent.dad}}!</p>
<p>Hello {{parent.mom}}!</p>
<span ng-click=parent.methodclick()>Parent Click </span>
</div>
<div ng-controller="ChildCtrl as Children">
<p>Hello {{Children.child.dad}}!</p>
<p>Hello {{Children.child.mom}}!</p>
<span ng-click=Children.child.methodclick()>Child Click </span></br>
<span ng-click=Children.child.methodclick1()>Separate Child Click </span>
<input ng-model="Children.child.Name" />
<span >{{Children.child.Name}}</span>
</div>
</body>
</html>
Demo
I have created a demo on plunkr with this code, here is the link to it: