Understanding Isolation in Directives
The scope hierarchy shown in the Batarang Chrome Dev Tool extension accurately represents the real scope tree. An isolate scope does not inherit from its surrounding scope, instead, it references it using the $parent
property.
Starting from Angular version 1.2.0, the content within an element controlled by an isolate scope directive is evaluated against the outer scope!
The official change log outlines these key points:
- $compile:
- As of d0efd5ee, child elements defined either in the main application template or in other directives' templates do not share the isolate scope. This behavior should not be relied upon, as it's uncommon - typically isolate directives come with their own templates.
- Following 909cabd3, directives without an isolate scope will not receive the isolate scope from a neighboring isolate directive on the same element. If your code relies on this scenario (non-isolate directive needing access to state within the isolate scope), adjust the isolate directive to use scope locals for explicit passing.
To grasp this concept better, consider the following HTML snippet:
<body ng-app="plunker">
{{$id}} / {{$childId}}
<div isolate-dir>
{{$id}} / {{$childId}}
<div not-isolate-dir>
{{$id}} / {{$childId}}
</div>
</div>
</body>
And the accompanying JavaScript code:
angular.module('plunker', [])
.directive('isolateDir', function() {
return {
scope: {},
link: function(scope) {
scope.$parent.$childId = scope.$id;
}
}
})
.directive('notIsolateDir', function() {
return { };
});
Feel free to check out the live example on Plunker.
In this setup, we expose the isolated scope's $id
outside the actual scope as the $childId
scope property.
Now let's compare the outputs:
- For Angular versions prior to 1.2.0rc1 (< 1.2.0): The
$childId
cannot be accessed since it was defined in the outer scope, and the interpolation strings within the isolated element are evaluated against the isolate scope.
002 / 003
003 /
003 /
- With Angular version 1.2.0 and above: The same interpolation strings reference the outer scope, displaying the value of
$scopeId
!
002 / 003
002 / 003
002 / 003
Important Note: When using directive templates, this distinction doesn't apply! In that case, you'll observe the first output described earlier.
Your Scenario
directiveTwo
doesn't utilize an isolate scope even when attached to a child of the directiveOne
element.