scope is an object that acts as shared context between the view and the controller enabling the two layers to exchange information related to the application model. The synchronization is enabled by a mechanism called two-way binding.
Two-way data binding
Traditional web applications were commonly developed through a one-way data binding mechanism. This meant there was only a rendering step that attached data to a view. This usually required developers to write a lot of boilerplate code which managed the writing and reading of values In two-way binding the view and controller are always kept synchronised with the need of boilerplate code.
$apply and $watch
When AngularJS is initialized on a web page, the compiler walks through the DOM tree looking for directives , when it finds the ngModel directive attached to any kind of input field, it binds its own scope’s $apply function to the onkeydown event. This function is responsible for invoking the notification process of the framework called the digest cycle.
This cycle is responsible for the notification process by looping over all the watchers, keeping them posted about any change that may occur in the scope. There are
situations where we might need to invoke this mechanism manually by calling the $apply function directly, as follows:
On the view the components responsible for displaying content of an element present inside the scope use their scope’s $watch function to be notified
about the changes on it. This function observes whether the value of a provided scope property has changed. To illustrate the basic usage of the $watch function,
let’s create a counter to track the number of times the value of a scope property has changed.
If you have been following with the rest of the code in this Angular Tutorial we’ll quickly amend our Second Iteration code (Code available on GitHub ) and create a counter that counts the number of characters in the summary box as the user types.
On the view if we add the following:
There are a few best practices to keep in mind when working with scope. The key point ot remember is that scope is not the model itself – it’s just a way to reach it. The view and controller layers are free to share any kind of information, even properties that are not related to the model, and they only exist to fulfil specific layout matters i.e. conditionally showing or hiding fields.
Avoid making changes to the scope directly from the view
We should avoid making changes to the scope by creating or modifying its properties directly inside the view. At the same time, we need to take care about reading the scope directly everywhere inside the controller.
Avoid reading the scope inside the controller
Reading the $scope object inside the controller instead of passing data through parameters should be avoided. This will negatively impact coupling between them resulting in making the controller difficult to test.
Do not let the scope cross the boundary of its controller
Take about not allowing the scope object to be used outside of the controllers boundary i.e. never pass it as a parameter to another service function.
Use a ‘.’ inside the ngModel directive
The framework provides the ability to create an object automatically when we introduce a period in the middle of the ngModel directive. Without that, we ourselves would need to create the object every time by writing much more code.
Avoid using scope unnecessarily
we should use $scope only when there are things to be shared with the view; otherwise, use a local variable to do the job.
The $rootScope object is inherited by all of the $scope objects within the same module. It is very useful and defines global behavior. It can be injected inside any
component such as controllers, directives, filters, and services; however, the most common place to use it is through the run function of the module API