-1

If a directive is using a controller directly, why is calling a method on the controller by referring the controller by its alias, not doing anything?

Imagine we have the following piece of code:

var app = angular.module('App', []);

    app.controller('MyController', ['$scope', function($scope) {
      $scope.doAction = function() {
        alert("controller action");
      }

      this.doAction2 = function() {
        alert("controller action 2");
      }
    }]);

    app.directive('myDirective', [function() {
      return {
        restrict: 'E',
        scope: {},
        controller: 'MyController',
        controllerAs: 'myCtrl',
        bindToController: true,
        template: "<a href='#' ng-click='myCtrl.doAction()'>Click it!<a><br><a href='#' ng-click='myCtrl.doAction2()'>Click it #2!<a> " ,
        link: function($scope, element, attrs, controller) {
          console.log($scope);
        }
      }
    }]);

While the first link won't work, the second will. To make the the first one work, I'd have to drop the alias, i.e. instead of calling the action by ng-click='myCtrl.doAction()' to call it as: ng-click='doAction()'

Shouldn't it work using the alias too? I mean, you are much more likely to find and reuse a controller, where the developers have attached actions to the $scope object and not to this

Preslav Rachev
  • 3,983
  • 6
  • 39
  • 63
  • It's seems from your last sentence that you've perfectly understand the difference between `this` (the controller object) and `$scope` (a variable accessible by injection in the controller and in which the template look for). If your question is "why is it design that way?", it's off topic here. If not, please clarify. – Blackhole Jun 06 '15 at 18:33

1 Answers1

0

ControllerAs exposes the controller instance on the scope under $scope[alias].

In your example, the scope looks (conceptually) like this:

$scope = {
  $id: 5,
  myCtrl: {
    doAction2: function(){...}
  },
  doAction: function(){...}
}

So, you can see why ng-click="myCtrl.doAction()" doesn't work.

The Controller-As approach has some benefits over directly exposing properties on the scope - one is that it does not pollute the scope (and its descendants) with properties that they may not need. It also inherently provides the dot-approach (.) to work properly with ng-model. You can find more information in this SO question/answer.

Community
  • 1
  • 1
New Dev
  • 48,427
  • 12
  • 87
  • 129