Reputation: 2468
Came across something interesting while experimenting. For some reason I am able to access the scope of a controller specified inside a directive declaration from outside the directive.
Here is the sample code:
myApp.directive('lockToggle', function () {
return {
restrict: 'A',
link: function (scope, elem) {
elem.bind('click', function (e) {
scope.locked = !scope.locked;
scope.$apply();
});
},
controller: function ($scope) {
$scope.locked = false;
$scope.hello = function () {
alert('hello');
};
}
};
});
and here is my markup:
<button lock-toggle>
Toggle Lock
</button>
<button ng-disabled="locked" ng-click="hello()">
Click Me!
</button>
When I click on the button Toggle Lock
, the Click Me!
button disables and enables correctly. And, when I click the Click Me!
button, the method hello()
on the controllers scope is called.
My question is why? Shouldn't the scope of the controller declared in the directive be isolated to the directives scope in the html? I would expect it to behave in the same way as other controllers, e.g.:
<!--Can't access the scope of MyController-->
<div ng-controller="MyController">
.
.
<!--CAN access the scope of MyController-->
.
.
</div>
<!--Can't access the scope of MyController-->
But for some reason, this doesn't seem to apply to my earlier example above. Why is this?
Upvotes: 3
Views: 3467
Reputation: 28578
The reason it is accessible is that you are adding it to same scope shared by your parent controller:
controller: function ($scope) {
$scope.locked = false;
$scope.hello = function () {
alert('hello');
};
}
Here $scope is of your parent controller and since in JavaScript object is by reference so you adding it to your parent controller.
If you want to initialize variable only for directive scope then use scope:
scope:{
//properties
}
Upvotes: 1
Reputation: 3327
You can decide how your directive scope should behave and if it shall inherit from the parent scope:
myApp.directive('lockToggle', function () {
return {
restrict: 'A',
scope: {}, // Will create an isolated scope
link: function (scope, elem) {
elem.bind('click', function (e) {
scope.locked = !scope.locked;
scope.$apply();
});
},
controller: function ($scope) {
$scope.locked = false;
$scope.hello = function () {
alert('hello');
};
}
};
});
Currently, you do not specify a scope
attribute, which is equal to scope:false
. Therefore, the directive does not create a scope.
Further information
Upvotes: 3