Dynamically Attaching controllers to a directive

January 31, 2015
by Rahil Shaikh

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

Lets 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.

Lets 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.

Lets 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 better understanding. here.

About

Engineer. Blogger. Thinker. Loves programming and working with emerging tech. We can also talk on Football, Gaming, World Politics, Monetary Systems.

Get notified on our new articles

Subscribe and get AngularJS Tips PDF. We never spam!
First Name:
Email:

3 comments

  1. Max
    |

    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 😉

Leave a Comment