Understanding $scope chaining in AngularJS
This article will help you understand how $scope chaining works in case of nested controllers. As a pre-requisite, you should be aware of the basics of angularJS and how to create controllers and attach them to the view.
Simple Example
We will consider an example of 2 controllers, both having data in ‘numVal’ which is binded to input fields and displayed as paragraph.
Below you will find the code for the above application.
As you can see from above images, we have 2 controllers, the inner controller is nested inside the outer controller. Both controllers try to access ‘numVal’ and in the view (html) we use ‘numVal’ from both controllers $scope. when we load the application, we only update the ‘numVal’ in the outer $scope. Lets check the console logs to get better understanding.
It is clear that only the outer $scope has numVal = 0. The inner $scope has no such property, but the fascinating part is that our application when loaded shows the initial value of 0 even for inner controller (check application image above).
$scope chaining
The behavior observed above is because the $scope chain works like the prototype chain of JavaScript. Initially when we try to access ‘numVal’ in inner controller, first the existence of numVal is checked in the $scope of inner controller. if not found, then we move up the chain and check in the parent/outer $scope. It is because of this that even in inner controller we are able to get the initial value as 0 even if ‘numVal’ does not exist in $scope of inner controller.
Something strange?
Now try using the input field or button of parent controller (the first input field and button are part of outer controller), to change ‘numVal’. you will observe that changes are reflected in child controller as well. Nothing strange here as per the above ‘$scope chaining’ explanation.
Now try using child controller to change the value. you will observe that only the child controller values get updated.
This happens because when we update ‘numVal’ from child controller, a copy is created in the $scope of child controller.
since we now get ‘numVal’ in child controller there is no need to move up the scope chain and hence now the values are detached, if you try to update parent controller values, they will no longer change the child controller values.
Conclusion
The above understanding helps solve a lot of strange scenarios that you may run into while working with angularJS in your applications. In case you are wondering where the scope chain ends, it ends at the $rootScope for which I will try to post a separate article. Another topic of discussion is how to write code which is safe from the above behavior and provides more consistency (hint: using controller as syntax).
Meanwhile, Happy Coding !!!