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.