SCOPE DESTRUCTION: Directive scope is never destroyed if immediately switched out and it has templateUrl. #9197
Description
We have a directive which uses templateUrl
that is rendered within a ngSwitch
. There is a scenario where on page load the directive is rendered, but then immediately some conditions change causing ngSwitch
to remove the directive from page. I found that in that case the directive's scope never gets destroyed.
A Plunker demo is available here - http://plnkr.co/edit/QYnUKQrHA4uivJifsYne?p=preview
In the demo open browser's JS console. Notice that you will only see '>>>Created' message, but no '>>>Destroyed'. This bug happens only when the directive uses templateUrl
. If you change the above demo code to use template
instead then notice the bug is gone.
The html snippet is:-
<body ng-controller="Main">
<div>
<div ng-switch="code">
<div ng-switch-when="red">
<red></red>
</div>
</div>
</div>
</body>
The controller code is:-
controller('Main', function ($scope, $timeout) {
$scope.code = 'red';
$timeout(function () {
$scope.code = 'blue';
})
})
So as soon as the controller loads, $scope.code
is set to 'blue' in next digest cycle, causing the directive red
to appear momentarily.
The directive code is:-
directive('red', function () {
return {
restrict: 'E',
replace: true,
templateUrl: 'red.html',
scope: {},
link: function (scope) {
console.log('>>>Created');
scope.$on('$destroy', function (event) {
console.log('>>>Destroyed');
})
}
};
})
If I use template
instead of templateUrl
, then $destroy
is called. The replace: true
or isolated scope are not necessary to replicate this bug.