Here are two directives:
aDirective that creates a new isolated scope;
bDirective does not create a new scope.
app.directive('aDirective', [function () {
return {
restrict: 'A',
scope: {}, // isolated scope
link: function (scope, iElement, iAttrs) {
}
};
}])
.directive('bDirective', [function () {
return {
restrict: 'A',
scope: false,
link: function (scope, iElement, iAttrs) {
}
};
}]);
Now apply these two directives to one DOM element:
<div ng-app="myApp">
<div ng-controller="myController">
<input id="targetElement" type="text" a-directive b-directive />
</div>
</div>
And the result what i get is it retrieves the scope of the target element.
//true
angular.element("#targetElement").isolateScope().$parent
=== angular.element("#targetElement").scope()
So my question is why a single DOM element owns two scopes (non-isolated scope and isolated scope ) at same time.
Its because in the first directive you are having an isolated scope which means it will have its own scope but if you check its parent object , you will still find the parent controller there.
Lets say if I have my controller like below
app.controller('myController', function($scope) {
$scope.obj='abc'
})
where I'm having only one property named obj
CASE 1: Isolated scope Now if I create my directive like yours
app.directive('aDirective', [function () {
return {
restrict: 'A',
scope: {}, // isolated scope
controller: function ($scope) {
console.dir($scope)
},
link: function (scope, iElement, iAttrs) {
console.log('From aDirective')
console.dir(scope)
}
};
}])
Here the scope is isolated which means that the directive will not share any property of the parents controller. But if want to have the properties which are declared in the controllers scope you can by accessing the parent proprety of the scope variable .
In the following image I'm trying to show the object hierarchy in isolated scope
In the above image you can see there is no obj property at the top level but you can see it in $parent property of the object, which is actually the parent controllers scope like below
CASE 2: Shared scope
Now in the directive where my scope is not isolated and its actually shared like below
app.directive('bDirective', [function () {
return {
restrict: 'A',
scope: false,
controller: function ($scope) {
console.dir($scope)
},
link: function (scope, iElement, iAttrs) {
console.log('From bDirective')
console.dir(scope)
}
};
}]);
Here when I'll explore the object hierarchy of the scope object I will find the obj property at top only, there is no need for the $parent property to get the properties declared in the parent controller because you are sharing the scope.
Now coming back to your question
//true
angular.element("#targetElement").isolateScope().$parent
=== angular.element("#targetElement").scope()
the above code will always return true as both are using the same controller, and you are comparing $parent object of isolated scope with shared scope which is nothing but the controller's scope only.
If you comapare
angular.element("#targetElement").isolateScope()
=== angular.element("#targetElement").scope()
you will get false.
Also at max there could be only two scopes when you are using a directive i.e parent scope and the directives scope.
Since you have created one scope with isolated and other with shared scope, hence the rule of having at max two scope is fulfilling and that is why its working.
If your directives have scopes like below it will not work and give you exception(if both directives are decorated on one element)
Directive1-> {} and Directive2 -> {}
Directive1-> {} and Directive2 -> true
Directive1-> true and Directive2 -> {}
Hence the only way you directives will work if the scopes are like below (if both directives are decorated on one element)
Directive1-> {} and Directive2 -> false
Directive1-> false and Directive2 -> {}
Directive1-> false and Directive2 -> false