An Introduction to Angular Controllers and Scope


Warning: Illegal string offset 'filter' in /var/sites/t/theproactiveprogrammer.com/public_html/wp-includes/taxonomy.php on line 1409

This post is the second in a series looking at some of the fundamental concepts of Angular. Click here to read the first part.

What is a Controller?

The easiest way to think about controllers and their role is like this:

The purpose of a controller is to add stuff to a scope.

This definition may sound simple, but it is accurate.  There is a lot more that can be said about controllers of course, some of which we will discuss below, but when using a controller in Angular, you are adding stuff to a scope, where that ‘stuff’ consists of functions and properties.

So what is a Scope?

Scopes are simply JavaScript objects which together represent your model. In some ways they are similar to the objects in a traditional object-oriented system: they contain properties and functions, and can inherit from each other*. Whenever you update your model through an input field or inside of a controller, you are in fact updating a property on a scope.

Every Angular application has one root scope, which then has child scopes, which have their own child scopes and so on, forming a scope hierarchy.

Wouldn’t it be simpler to have just one Scope object?

No – the scope hierarchy exists so that you can only access specific parts of the model from any one place in a template, and also to make your application more modular.

Having one scope object would be a bit like declaring everything as a global variable – which we all know isnt a good idea.

How is the Scope Hierarchy created?

Every time we use the ng-controller directive in a template, a new child scope is created and injected into an instance of the specified controller. This child scope will now be accessible within our controller function. On our template (i.e. our HTML), the scope object is accessible from anywhere within the element on which the ng-controller attribute exists.

So in the example below, we can access all three of the declared controllers inside our productDiv.

 

Plunker

I’m not seeing a Scope object.

When we refer to ‘this’ inside our controller definition as above, we are actually accessing the newly created child scope.

Prior to Angular v1.2, we would have had to reference the scope object explicitly, like this:

Plunker

Explicitly injecting the new $scope object and accessing it in this way still works, it is up to you which approach you choose.

In addition to adding and updating properties on our scope, we can of course add functions which we can call from our template:

Plunker

So each ‘child scope’ is associated with the DOM element where the ng-controller attribute is specified. What about the ‘root’ scope?

The root scope is associated with the element where the ng-app attribute is specified.

How does the template know when a property on the scope is changed, as in the applyDiscount function above?

As Jim Hoskins explains, JavaScript runs in turns, and at the end of each turn Angular uses dirty-checking** to see what has changed. The function which checks if any model properties have changed is $scope.$digest(), which is called by $scope check that.$apply(). We generally don’t need to concern ourselves with these functions, as they are taken care of under the hood by Angular***.

Having now introduced Angular directives, controllers and scope, in the next part of this series we will turn our attention to Angular services.

* In other words, Angular takes advantage of JavaScript’s built in prototypal inheritance features when constructing the scope hierarchy.

** Angular differs from Ember and Backbone in this respect, as these frameworks use accessors as opposed to dirty-checking.

*** If we are updating our model from code which lies outside of Angular however, we need to manually run that code using $scope.$apply() so that Angular knows it needs to check for modifications.

Share Buttonvar hupso_services_t=new Array(“Twitter”,”Facebook”,”Google Plus”,”Linkedin”,”Digg”,”Reddit”);var hupso_background_t=”#EAF4FF”;var hupso_border_t=”#66CCFF”;var hupso_toolbar_size_t=”medium”;var hupso_image_folder_url = “”;var hupso_url_t=””;var hupso_title_t=”An Introduction to Angular Controllers and Scope”;http://static.hupso.com/share/js/share_toolbar.js
Share Button