Reputation: 396
I just started out with Angular and have been reading through a lot of Tutorials.
Now the free one at CodeSchool which was my starting point doesn't mention $scope
at all.
From what I've gathered, the controllerAs
syntax is relatively new (1.2.0) but it seems to allow you to get away without using $scope
directly.
Some articles say "use controllerAs
" with an explanation, but most just use $scope
. But I couldn't find any explanation why they'd choose it.
Is this now mainly a case of favoring one over the other or are there still reasons to use $scope
?
Even many new directive plugins use it instead of allowing you to bind it to a particular controller.
edit: To clarify, I want to know when to use $scope
, not the reasons not to use it :)
Upvotes: 12
Views: 2079
Reputation: 1019
The best answer I can give you is this:
The short:
Scope
.ngController
.The long:
Scope
or $scope
, as you've put it, is where we maintain values (no matter the type: Function, Object, String, etc.) that may be available to the template within that scope. For example, consider the following:
The HTML:
<div ng-controller="MyCtrl">
<div>{{ message }}</div>
</div>
<div ng-controller="MyCtrl as ctrl">
<div>{{ ctrl.message }}</div>
</div>
See those interpolations? Well, guess what? They're both accessing Scope
. The "controller as syntax" creates an alias for MyCtrl
and publishes it on the local scope. Once the element has been linked, if you look at $scope
you will actually find a property ctrl
that exposes the controller.
The Javascript
function MyCtrl($scope) {
$scope.message = "controller MyCtrl";
this.message = "controller as syntax";
}
Where ever I use MyCtrl
these two messages are available. But to readily access a value on the controller itself we use the "controller as alias" syntax.
They are honestly two different methodologies. The controller as * syntax allows the developer to put the controller onto the scope and more easily access said controller. So, in the end it all ends up on the scope. Otherwise, say through a directive's link function, you have to access the controller the require
property. The controller's methods and properties don't necessarily need to be exposed to the template, rather just used in the logic. (In addition, you can access a controller through a jqLite's data() function as well).
Sometimes when propagating a controller to multiple elements we want something that is available by default to every element that uses this controller. This is particularly valuable when creating directives. Take a look at ngModel and see how we have multiple methods common to every element that uses ngModel.
The major thing to consider is that a child controller can inherit the scope of it's parent. The cool thing is that the child scope will inherit that bit of parental controller properties from the parent.
<!-- ctrl1 -->
<div ng-controller="MyCtrl as ctrl1">
<div>{{ ctrl1.message }}</div>
<!-- ctrl2 -->
<div ng-controller="MyCtrl as ctrl2">
<div>{{ ctrl2.message }}</div>
</div>
</div>
Notice that both are using the same controller but they have different aliases. Now, the controller properties are being passed down to the children through Scope
. So the child can access the parent through it's alias. So, through this syntax you can clearly see the separation of the two instances of MyCtrl. They both have a message
property on their scopes, but they are easily distinguished without digging through parents, children, siblings, etc.
If you want to expose values to the template use scope. If you want to bind values to an element that don't necessarily need to be exposed in the template, use the controller. If you need to access values from your controller in your template, use the controller as syntax. Using the controller as * syntax places the controller's values on the scope under the alias created in the syntax. So, in that case, you are using both the controller and the scope together.
Upvotes: 4
Reputation: 478
I read a few blogs and came to a conclusion for usage purpose do not mix $scope and this. There is a reason for that , "this" and $scope can be different they are not always the same for example- If I have defined a controller on "this" and I call another controller in it then the $scope will be set to the controller I called but "this" will always be the current context that is the controller in which I called the other controller. So in this case $scope and "this" will not be same and using them interchangeably here may lead to some unexprcted behaviour.
Please correct me If I am wrong.
Upvotes: 0
Reputation: 1062
In the Angular documentation for ngController it explains the advantages to using 'controller as' vs. injecting $scope. Here's what it says:
- Using controller as makes it obvious which controller you are accessing in the template when multiple controllers apply to an element.
- If you are writing your controllers as classes you have easier access to the properties and methods, which will appear on the scope, from inside the controller code.
- Since there is always a . in the bindings, you don't have to worry about prototypal inheritance masking primitives.
For my own part I've found using 'controller as' quite beneficial as it forces me to consider whether code I'm adding to a controller would be more appropriately added into a service or directive.
For example: watches. Watches are something you should avoid in controllers but having easy access to $scope allows you to set them up easily. Using 'controller as' has forced me to think more carefully about whether I really need to do a watch. Usually a watch can be accomplished with a directive. This has led me to create smaller controllers that only set up an initial state and communicate with services, a pattern I've found much more performant and maintainable.
Upvotes: 12
Reputation: 27
As stated in the Angular documentation the benefits are
I really like it since it makes it easy to differentiate between which controller I am currently accessing.
Upvotes: 1