Scopes

Scopes are a core fundamental of any Angular app. They are used all over the framework, so it’s important to know them and how they work.

The scopes of the application refer to the application model. Scopes are the execution context for expressions. The $scope object is where we define the business functionality of the application, the methods in our controllers, and properties in the views.

Scopes serve as the glue between the controller and the view. Just before our app renders the view to the user, the view template links to the scope, and the app sets up the DOM to notify Angular of property changes. This feature makes it easy to account for promises, such as an XHR call, to be fulfilled. See the promises chapter for more details.

Scopes are the source of truth for the application state. Because of this live binding, we can rely on the $scope to update immediately when the view modifies it, and we can rely on the view to update when the $scope changes.

$scopes in AngularJS are arranged in a hierarchical structure that mimics the DOM and thus are nestable: We can reference properties on parent $scopes.

If you are familiar with JavaScript, then this hierarchical concept shouldn’t be foreign. When we create a new execution context in JavaScript, we create a new function that effectively creates a new “local” context. The Angular concept of $scopes is similar in that as we create a new scope for child DOM elements, we are creating a new execution context for the DOM to live in.

Scopes provide the ability to watch for model changes. They give the developer the ability to propagate model changes throughout the application by using the apply mechanism available on the scope. We define and execute expressions in the context of a scope; it is also from here that we can propagate events to other controllers and parts of the application.

It is ideal to contain the application logic in a controller and the working data on the scope of the controller.

The $scope View of the World

When Angular starts to run and generate the view, it will create a binding from the root ng-app element to the $rootScope. This $rootScope is the eventual parent of all $scope objects.

The $rootScope object is the closest object we have to the global context in an Angular app. It’s a bad idea to attach too much logic to this global context, in the same way that it’s not a good idea to dirty the JavaScript global scope.

This $scope object is a plain old JavaScript object. We can add and change properties on the $scope object however we see fit.

This $scope object is the data model in Angular. Unlike traditional data models, which are the gatekeepers of data and are responsible for handling and manipulating the data, the $scope object is simply a connection between the view and the HTML. It’s the glue between the view and the controller.

All properties found on the $scope object are automatically accessible to the view.

For instance, let’s say we have the HTML:

<div ng-app="myApp">
  <h1>Hello {{ name }}</h1>
</div>

We can expect the {{ name }} variable to be a property of the containing $scope:

angular.module('myApp', [])
  .run(function($rootScope) {
    $rootScope.name = "World";
});

logo

It’s Just HTML

Our app renders our HTML and delivers it to the browser for presentation. This HTML contains all standard HTML elements, both Angular-specific and non-Angular-specific. The elements that do not contain Angular-specific declarations are left unmodified.

<h2>Hello world</h2>
<h3>Hello {{ name }}</h3>

In the previous example, Angular won’t touch the <h2> element, while it will update the <h3> with any scope modifications.

Through Angular, we can use different types of markup in a template. These types include the following:

What Can Scopes Do?

Scopes have the following basic functions:

The majority of the work we’ll do in developing our Angular app is building out the functionality of a scope.

Scopes are objects that contain functionality and data to use when rendering the view. It is the single source of truth for all views. You can think of scopes as view models.

In the previous example, we set a variable name on the $rootScope and reference it in a view, like so:

angular.module('myApp', [])
  .run(function($rootScope) {
    $rootScope.name = "World";
});

And our view can now reference this name property to show to the user:

<div ng-app="myApp">
  <h1>Hello {{ name }}</h1>
</div>

Instead of placing variables on the $rootScope, we can explicitly create a child $scope object using a controller. We can attach a controller object to a DOM element using the ng-controller directive on a DOM element, like so:

<div ng-app="myApp">
  <div ng-controller="MyController">
    <h1>Hello {{ name }}</h1>
  </div>
</div>

Now, instead of attaching the name variable on the $rootScope, we can create a controller that will manage our variable:

angular.module("myApp", [])
.controller('MyController',
function($scope) {
  $scope.name = "Ari";
});

The ng-controller directive creates a new $scope object for the DOM element and nests it in the containing $rootScope.

$scope Lifecycle

When an event occurs in the browser that angular cares about, such as a user typing into an input field that is watched by the ng-model attribute or a button with the ng-click attribute is clicked the angular event loop will get started. The event will be processed inside the Angular execution context.

For more information on the Angular execution context, check out the digest loop chapter.

When the event is handled, the $scope will evaluate the expression. The event loop starts and the application checks each watch.

We’ll dive deep into expressions in the Expressions chapter. The scope’s expression is whatever we set the scope variable to. When we set the scope name above, we’re setting it to an expression: $scope.name = "Ari", even if it’s just a string.

The $scope object lifecycle is handled for us in four distinct stages:

Creation

When a controller or directive is created, Angular creates a new scope for us and passes this on to the new scope when it runs the controller constructor function at runtime. We don’t need to worry about how it is created, we can just depend upon it being created for us.

Linking

When angular start running, all of the $scope objects are attached or linked to the view. All functions that create $scope objects attach themselves to the view as well. These scopes will register functions that run when things change in the context of the angular app.

These functions are called $watch functions, which is how Angular knows when to start the event loop.

Updating

When the event loop is running, which usually executes on the top-most $scope object (called the $rootScope), every child scope performs it’s own dirty checking. Every watch function is checked for changes. If any changes are detected, then the $scope object will fire the callback.

Destruction

When a $scope object is no longer needed in the view, the scope itself will be cleaned up and destroyed.

Although we’ll never need to clean up the scope directly as angular handles this for us, it’s useful to know that whomever created the scope will clean up the scope for us using a method on the $scope called: $destroy().

Directives and Scopes

Directives, which are used all throughout our Angular apps, generally do not create their own $scopes, but there are cases when they do. For instance, the ng-controller and ng-repeat directives create their own child scopes and attach them to the DOM element.

But before we get too far, let’s take a look at what controllers are and how we can use them in our applications.

 
This page is a preview of ng-book.
Get the rest of this chapter plus 600 pages of the best Angular content on the web.

 

Ready to master AngularJS?

  • What if you could master the entire framework – with solid foundations – in less time without beating your head against a wall? Imagine how quickly you could work if you knew the best practices and the best tools?
  • Stop wasting your time searching and have everything you need to be productive in one, well-organized place, with complete examples to get your project up without needing to resort to endless hours of research.
  • You will learn what you need to know to work professionally with ng-book: The Complete Book on AngularJS or get your money back.
Get it now