In this lesson we will learn a way to dynamically attach controllers to a directive, the reason I’m calling this dynamic is that here we will specify the directive, the name of the controller it is supposed to use, via an attribute.
However, an important point to note is that this requires the scope to be isolated, which we have already learned in our previous lesson.
View Demo:here
Download Code:here
Let’s first have a look at our two controllers.
var testApp = angular.module('testApp',[]);
testApp.controller('controllerOne',function($scope){ //controller one
$scope.ctrlHits = 0;
$scope.displaytext = 'Click to see the name of the controller used.';
$scope.invoked = function(){ //Will call this function on change and update the value of displaytext & ctrlHits variables.
$scope.displaytext = 'controllerOne Hits';
$scope.ctrlHits++;
}
});
testApp.controller('controllerTwo',function($scope){ //controller two
$scope.ctrlHits = 0;
$scope.displaytext = 'Type in to see the name of the controller used.';
$scope.invoked = function(){ //Will call this function on change and update the value of displaytext & ctrlHits variables.
$scope.displaytext = 'controllerTwo hits';
$scope.ctrlHits++;
}
});
Both of these controllers have a function $scope.invoked() which will increment the value of $scope.ctrlHits.
Let’s Add our directive to this.
testApp.directive('myDirective',function(){
return {
restrict:'E',
scope:{},
template:'<label>My Directive: <input type="button" value="click me" class="btn btn-success" ng-model="userinput" ng-click="invoked()" class="form-control"/></label>'
+'<p>{{displaytext}} : {{ctrlHits}}</p>',
controller:'@', //specify the controller is an attribute
name:'ctrlName' //name of the attribute.
}
});
Here above if you look at ‘controller:’@’‘ this specifies the directive that the controller is passed as an attribute.
Then in the name:’ctrlName’ we pass the name of the attribute.(ctrl-name in html)
Note: ctrlName is the name of the attribute to which the controller name is passed and not the name of the controller itself.
We also have a button in template that will call the $scope.invoked() function whenever clicked.
Let’s have a look at the HTML
<html>
<head>
<link href="css/bootstrap.min.css" rel="stylesheet" media="screen" />
<link href="css/bootstrap-theme.min.css" rel="stylesheet" media="screen"/>
</head>
<body ng-app="testApp">
<div class="container">
<div class="row">
<div class="col-md-3">
<h4>Directive with controllerOne.</h4>
<my-directive ctrl-name="controllerOne">
</my-directive>
</div>
<div class="col-md-3">
<h4>Directive with controllerTwo.</h4>
<my-directive ctrl-name="controllerTwo">
</my-directive>
</div>
</div>
</div>
</body>
<script src="https://code.angularjs.org/1.2.27/angular.min.js"></script>
<script src="js/testApp.js"></script>
</html>
Html Syntax to add controller via attribute
<my-directive ctrl-name="controllerOne"></my-directive>
<my-directive ctrl-name="controllerTwo"></my-directive>
Note: The attribute name ‘ctrl-name’ will be written as ‘ctrlName’ (Camel Case) in the directive(js file)
Here above you can see the same directive (my-directive) is using two different controllers the one declared at the top will be using controllerOne and the other controllerTwo.
Check out the demo for a better understanding. here.
Excellent! I have no idea, why it’s not covered in official docs?
Thanks Max!
Even I’m not sure why it is not included in Official docs
but the good thing is we know it now 😉
why we need this. while we already have ng-controller ?