4

learning angular so some time things not clear when read article on angular. here i stuck to understand what is the usage or importance of this keywords Controller and controllerAs in directive.

code taken from here http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html

app.controller('SomeController', function () {
  this.foo = 'bar';
});

app.directive('someDirective', function () {
  return {
    restrict: 'A',
    controller: 'SomeController',
    controllerAs: 'ctrl',
    template: '{{ctrl.foo}}'
  };
});

i like to know understand the importance of this two keywords in directive and they are controller: 'SomeController', and controllerAs: 'ctrl',

please tell me if we do not use these two keyword controller: 'SomeController', and controllerAs: 'ctrl', then what would happen or what would be worse ?

please help me to understand the usage or importance of this keywords controller: 'SomeController', and controllerAs: 'ctrl', in directive. thanks

Mou
  • 15,673
  • 43
  • 156
  • 275

4 Answers4

1

You need the controller if you plan on referencing a controller object. This is how you hook it up.

The controllerAs allows you to create a variable that you can reference the controller with in lieu of using the $scope.

Refined answer:

<html ng-app="app">

<head></head>

<body>
    <script src="node_modules/angular/angular.js"></script>
    <script>
        var app = angular.module('app', []);
        app.directive('fooDirective', function() {
        return {
                restrict: 'A',                       
                controller: function($scope) {
                    // No 'controllerAs' is defined, so we need another way
                    //  to expose this controller's API.
                    // We can use $scope instead.
                    $scope.foo = 'Hello from foo';
                },
                template: '{{foo}}'
            };
        });

        app.directive('barDirective', function() {
           return {
               restrict: 'A',
               controller: function() {
                   // We define a 'vm' variable and set it to this instance.
                   // Note, the name 'vm' is not important here. It's not public outside this controller.
                   //   The fact that the 'controllerAs' is also called 'vm' is just a coincidence/convention.
                   // You could simply use 'this.bar' if you prefer.
                   var vm = this;
                   vm.bar = 'Hello from bar';
               },
               // This allows us to reference objects on the controller's instance by
               //   a variable called 'vm'.
               controllerAs: 'vm',
               // Now we can reference objects on the controller using the 'controllerAs' 'vm' variable.
               template: '{{vm.bar}}'
           };
        });
    </script>

    <div foo-directive></div>
    <div bar-directive></div>
</body>

</html>
mariocatch
  • 8,305
  • 8
  • 50
  • 71
  • sorry not very clear because just hooking toward angular. so sometime things getting bouncer. can u explain with small example. thanks – Mou May 16 '16 at 14:05
  • thanks lot for your code. in my code it is there `controller: 'SomeController',` but in your code you declare controller function in directive itself. so like to know what is `SomeController` in my directive ? is it referring outer controller ? – Mou May 17 '16 at 09:36
  • my question is we create controller outside of directive then why should we create controller function like link option in directive? why we need to declare controller function or option in directive itself.....please help me to understand this need. thanks – Mou May 17 '16 at 09:43
  • @Mou, yes in your example the `controller: 'SomeController'` property means that directive is using an external controller in the same lexical scope. You don't have to use a controller with a directive. This SO link may help too: http://stackoverflow.com/questions/12546945/difference-between-the-controller-link-and-compile-functions-when-definin – mariocatch May 17 '16 at 18:42
1

You don't need to use both controller and controllerAs. You can use the shorthand:

controller: 'SomeController as ctrl'

The relationship is that a new instance of the controller is created and exposed to the template using the instance handle you provide as ctrl.

Where this comes in handy is if you are using nested controllers -- or using multiple instances of a controller in a view.

UPDATE TO ANSWER COMMENTS

You do not need to use controllers with AngularJS directives. Infact as of AngularJS 1.5 you should probably only use controllers when creating components rather than directives.

Directives and Components are conceptually similar. Up until AngularJS they all components would be defined as a directive.

In many ways a directive interacts with an element (like ng-href) or events (like ng-click).

The simplest way to differentiate Components and Directives is a Component will have a template.

Can't I just create a component using the directive link method?

You can, but I wouldn't recommend it unless you have a good reason. Using controllers allows you to use object oriented classes or prototypes to define the action behaviors with the template and user.

As well these controllers are extremely more easy to unit test than the directive link functions.

Martin
  • 15,820
  • 4
  • 47
  • 56
  • my question is we create controller outside of directive then why should we create controller function like link option in directive? why we need to declare controller function or option in directive itself.....please help me to understand this need. thanks – Mou May 17 '16 at 09:43
  • see my posted code `app.directive('someDirective', function () { return { restrict: 'A', controller: 'SomeController', controllerAs: 'ctrl', template: '{{ctrl.foo}}' }; });` this is referring my outer controller `controller: 'SomeController', ?` – Mou May 17 '16 at 09:45
1

One of its main advantages, especially if you're new to AngularJS, is that it ensures proper data binding between child scopes.

Just play around with this code sample and try to notice something strange:

angular
  .module('myApp', [])
  .controller('MainCtrl', ['$scope',
    function($scope) {
      $scope.truthyValue = true;

      $scope.foo = 'hello';
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>

<div ng-app="myApp" ng-controller="MainCtrl">
  <p>Start by writing something in the first input. Then write something in the second one. Good job, you've broke AngularJS!</p>
  1.
  <input type="text" ng-model="foo">

  <div ng-if="truthyValue">
    2.
    <input type="text" ng-model="foo">
  </div>

  <div>$scope.foo: {{ foo }}</div>
</div>

The reason behind it is that ngIf creates a child scope which inherits from the parent scope. You're basically changing the value inside ngIf's scope which doesn't affect the value from its parent scope.

Finally, I consider controllerAs syntax an important AngularJS best practice. If you get accustomed to it early in your learning process, you'd be avoiding a lot of head-scratching wondering why your code doesn't work, especially when everything seems in order.

Cosmin Ababei
  • 7,003
  • 2
  • 20
  • 34
0

Check out this plunkr code

Here is my simple Directive code:

angular.module('app', [])

.directive('someDirective', function () {
  return {
    scope: {},
    controller: function ($scope) {
      this.name = 'Pascal';
      $scope.color = 'blue';
    },
    controllerAs: 'ctrl',
    template: '<div>name: {{ctrl.name}} and Color: {{color}}</div>'
  };
});

And The HTML

<body ng-app="app">
   <some-directive />
</body>

So, as you can see, if you need to access some variable which were defined against this keyword in the controller, you have to use controllerAs. But if it was defined against $scope object you can just access it with its name.

For example, you can get the variable color just by using {{color}} as it was defined against $scope but you have to use {{ctrl.name}} as "name" was defined against this.

I don't think there really is much difference, as this answer says,

Some people don't like the $scope syntax (don't ask me why). They say that they could just use this

Also from their own website you can read the about the motivation behind this design choice,

Using controller as makes it obvious which controller you are accessing in the template when multiple controllers apply to an element

Hope it helps.

Community
  • 1
  • 1
Suman Barick
  • 3,311
  • 2
  • 19
  • 31
  • my question is we create controller outside of directive then why should we create controller function like link option in directive? why we need to declare controller function or option in directive itself.....please help me to understand this need. thanks – Mou May 17 '16 at 09:43
  • see my posted code `app.directive('someDirective', function () { return { restrict: 'A', controller: 'SomeController', controllerAs: 'ctrl', template: '{{ctrl.foo}}' }; });` this is referring my outer controller `controller: 'SomeController', ?` – Mou May 17 '16 at 09:44
  • Look, in your directive you don't **'have to'** define a controller. It is just an added feature if you want to use. Not a mandatory requirement. In angular world whenever there is no controller for a particular scope, that scope will automatically take variables and functions from its parent scope (controller) – Suman Barick May 17 '16 at 09:50
  • Say you are making a game where each enemy is a directive, say . Then you might want that each of enemy have their own set of speed, life, color etc and you might want each of them to move randomly / systematically depending on their intelligence level. In that case you will feel that, yeah, now I need a **brain** for each enemy (directive). That brain will be the controller function of that directive. Is it clear a bit now? – Suman Barick May 17 '16 at 09:54
  • @Mou Congrats :) Happy to help you :) – Suman Barick May 17 '16 at 10:58
  • i am new in ng. can u tell me what is the usage of `bindToController` keyword in directive ? – Mou May 17 '16 at 11:00
  • See the accepted answer here, it is clearly explained http://stackoverflow.com/questions/31861783/angularjs-1-4-directives-scope-two-way-binding-and-bindtocontroller – Suman Barick May 17 '16 at 11:03