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.

testApp.js
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.js
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

index.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.
image
Check out the demo for a better understanding. here.

3 Comments

Leave a Reply

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