Cannot Use ControllerAs this
Can anyone explain the following scenario to me, please?
Works
ng-controller="Parent as thus"
Breaks
ng-controller="Parent as this"
That single letter which makes it a keyword -- which I want -- wrecks the forest.
Why is this?
P.S. I'm aware of the vm
convention, but I find it disturbs portability of controllers/viewmodels.
The problem is certainly not that this
is a reserved word in JavaScript.
There is no rule in the controller as syntax that says you would need to assign the value of this
to a variable with the same name as the controller and I'm pertty sure angular won't do such thing either. Why would it? That would be incredibly stupid use of Function
constructor and just a needless bug.
There's a simple way to test that JavaScript reserved words are not the issue here. Name your controller "throw". "Parent as throw"
. throw
is a reserved word, but does that throw errors? No. Does that work? Yes.
this
is, however, reserved in the context of angular's own template expressions. It's used to refer to the current scope
of the expression.
<div ng-controller="Parent as this">
{{log(this)}}
</div>
angular.module('testApp', []).controller('Parent', function($scope){
this.test = 'foo';
$scope.log = function(arg){
console.log(arg);
};
});
The above won't throw errors, but it won't log the controller either. Instead, it will log a scope object containing the log
function and $parent
and what not.
In fact, it will also contain something intresting to us: property this: Object
, our controller.
And sure enough, change the template expression to {{log(this.this)}}
and it will log the controller instance just fine. Still wouldn't use 'this'
as the name though, it would probably just cause more bugs by mistake than undefined functions ever have.
You are cannot use this
as the instance name. this
is a reserved keyword.
It would be the equivalent of doing:
var this = new Controller();
You can see that is wrong. It should be something like:
var ctrl = new Controller();
This is essentially what angularJs does behind the scenes when you do controllerAs="Controller as ctrl"