CWagner
CWagner

Reputation: 396

When to use $scope directly?

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

Answers (4)

Stephen J Barker
Stephen J Barker

Reputation: 1019

The best answer I can give you is this:

The short:

  • Whenever you want to expose logic to the template, use Scope.
  • Whenever you want to persist logic to an element, use ngController.
  • If you want to expose your controller's values directly in the template (through the scope), use the "controller as syntax".

The long:

An Explanation

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.

Scope vs. Controller

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.

In Conclusion

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

Novice
Novice

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

JPRO
JPRO

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

MRog
MRog

Reputation: 27

As stated in the Angular documentation the benefits are

  • 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.

I really like it since it makes it easy to differentiate between which controller I am currently accessing.

Upvotes: 1

Related Questions