![]()
In AngularJS, $scope follows a hierarchical structure, meaning child controllers inherit properties and methods from their parent controllers. This mechanism allows data sharing but can also lead to unexpected behavior if not properly understood.
How $scope Inheritance Works
- Each controller has its own
$scope, but it inherits from its parent. - Child controllers can access parent properties, but modifications may create a new copy in the child scope.
- Inheritance follows JavaScript’s prototypal inheritance, meaning changes in objects (not primitives) reflect in both parent and child.
Example of $scope Inheritance
1️⃣ Basic Example
app.controller("ParentController", function($scope) {
$scope.message = "Hello from Parent!";
});
app.controller("ChildController", function($scope) {
// Child scope automatically inherits `message` from parent
});
HTML:
<div ng-controller="ParentController">
<p>Parent Message: {{ message }}</p>
<div ng-controller="ChildController">
<p>Child Message: {{ message }}</p>
</div>
</div>
Output:
Parent Message: Hello from Parent!
Child Message: Hello from Parent!
Since message is inherited, both parent and child can access it.
Issue with $scope Shadowing
When modifying primitive values (like strings, numbers) inside a child controller, it does not affect the parent scope due to scope shadowing.
2️⃣ Shadowing Issue Example
app.controller("ParentController", function($scope) {
$scope.username = "Narendra";
});
app.controller("ChildController", function($scope) {
$scope.username = "Sai Krishna"; // Creates a new local variable in the child scope
});
HTML:
<div ng-controller="ParentController">
<p>Parent Username: {{ username }}</p>
<div ng-controller="ChildController">
<p>Child Username: {{ username }}</p>
</div>
</div>
Output:
Parent Username: Narendra
Child Username: Sai Krishna
Issue:
- Child scope creates a new property (
username), which hides the parent’susernameproperty. - Parent scope remains unchanged.
Solution: Use Objects for Data Binding
To avoid shadowing, always use objects instead of primitives.
3️⃣ Fixing Shadowing Using Objects
app.controller("ParentController", function($scope) {
$scope.user = { name: "Narendra" };
});
app.controller("ChildController", function($scope) {
$scope.user.name = "Sai Krishna"; // Modifies parent object
});
HTML:
<div ng-controller="ParentController">
<p>Parent Username: {{ user.name }}</p>
<div ng-controller="ChildController">
<p>Child Username: {{ user.name }}</p>
</div>
</div>
Output (Updated in Both Parent & Child):
Parent Username: Sai Krishna
Child Username: Sai Krishna
Why?
- Objects are passed by reference, so changes reflect in both scopes.
$scope Inheritance Behavior in ng-repeat
When using ng-repeat, a new child scope is created for each iteration.
4️⃣ Example: $scope in ng-repeat
app.controller("ListController", function($scope) {
$scope.items = [{ name: "Item 1" }, { name: "Item 2" }];
});
<div ng-controller="ListController">
<ul>
<li ng-repeat="item in items">
<input type="text" ng-model="item.name">
</li>
</ul>
</div>
Each list item gets its own child scope, but updates still affect the parent’s array.
$scope and this in Controller As Syntax
Using this instead of $scope avoids scope inheritance issues.
5️⃣ Example: Using Controller As Syntax
app.controller("ParentController", function() {
this.message = "Hello from Parent!";
});
app.controller("ChildController", function() {
this.message = "Hello from Child!";
});
HTML:
<div ng-controller="ParentController as parent">
<p>Parent Message: {{ parent.message }}</p>
<div ng-controller="ChildController as child">
<p>Child Message: {{ child.message }}</p>
</div>
</div>
No scope shadowing issues because each controller manages its own instance.
