1

I recently read in angular documentation (https://code.angularjs.org/1.4.9/docs/guide/providers) this:

myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
  this.clientId = clientId;
}]);

associated to:

<html ng-app="myApp">
  <body ng-controller="DemoController as demo">
    Client ID: {{demo.clientId}}
  </body>
</html>

Then I was surprised because this was used instead of an injected $scope service.

I tried to reproduce with success, then I'm wondering if someone could explain one use-case where using controller instance is preferable to injected $scope?

G. Ghez
  • 3,429
  • 2
  • 21
  • 18

2 Answers2

3

See John Papa's style guide about controllerAs:

... the controllerAs syntax is closer to that of a JavaScript constructor than the classic $scope syntax

It promotes the use of binding to a "dotted" object in the View (e.g. customer.name instead of name), which is more contextual, easier to read, and avoids any reference issues that may occur without "dotting".

Helps avoid using $parent calls in Views with nested controllers.

The biggest benefit I've found in my general day-to-day use of this is the fact that it provides a concept of namespacing in controllers instead of just having this feeling of "free variables" roaming around your markup.

That's especially important if you have nested controllers, because it provides a way to namespace variables (even ones with the same name), but ensure they are in the context of the correct controller.

Community
  • 1
  • 1
Josh Beam
  • 19,292
  • 3
  • 45
  • 68
  • For namespacing variables on scope I'm using object hierarchy: `$scope.mynamespace = {var1: 5, var2: 6};` for example. – G. Ghez Feb 17 '16 at 18:53
  • @G.Ghez you're doing exactly what `controllerAs` does under the hood :) – Josh Beam Feb 17 '16 at 18:54
  • @G.Ghez, if you look at the Angular source code, you'll see that `controllerAs` is just a convenient way of doing `$scope.` – Josh Beam Feb 17 '16 at 18:54
  • It also provides dot notation out of the box so variables maintain reference – Sha Alibhai Feb 17 '16 at 20:32
  • I may agree, but then, could we just stop using `$scope` in favor of controller instance? I'm wondering about `$scope.$watch`, `.$on`... – G. Ghez Feb 18 '16 at 09:08
  • @G.Ghez, yes if you're going to still be using `$scope` for specific `$scope` methods like you mentioned, then you'll still have to inject `$scope` and use it. Angular 2 does away with that completely as far as I understand. – Josh Beam Feb 18 '16 at 20:40
1

Why it's better to use controller as is well described in this guide.

Why?: Controllers are constructed, "newed" up, and provide a single new instance, and the controllerAs syntax is closer to that of a JavaScript constructor than the classic $scope syntax.

Why?: It promotes the use of binding to a "dotted" object in the View (e.g. customer.name instead of name), which is more contextual, easier to read, and avoids any reference issues that may occur without "dotting".

Why?: Helps avoid using $parent calls in Views with nested controllers.

It's best however to use a specialized variable to access controller instance:

myApp.controller('DemoController', ['clientId', '$scope', function DemoController(clientId, $scope) {
  var self = this;
  self.clientId = clientId;

  //to watch the vars
  $scope.$watch('self.clientId', function(new, old) {});
}]);
Dmitri Pavlutin
  • 18,122
  • 8
  • 37
  • 41
  • where `$scope` here is coming from? ;) – G. Ghez Feb 18 '16 at 09:08
  • Also, I think, watcher should be applied to `clientId` only, not `self.clientId` – G. Ghez Feb 18 '16 at 10:13
  • @G.Ghez Nope, the `self.clientId` is correct. Please check this section: https://github.com/johnpapa/angular-styleguide#controlleras-with-vm – Dmitri Pavlutin Feb 18 '16 at 10:15
  • Then I have another concern explained in another question here: http://stackoverflow.com/questions/35483905/angularjs-scope-not-watching-changes-from-view – G. Ghez Feb 18 '16 at 14:18
  • 1
    @G.Ghez Yep, answered. The `self` should be used as the alias of the controller in the view: ng-controller="controller as self". – Dmitri Pavlutin Feb 18 '16 at 14:31
  • I understand this build, but I'm a little bit disturbed by hard link (named alias) it creates between controller and view. – G. Ghez Feb 18 '16 at 14:36