Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

SCOPE DESTRUCTION: Directive scope is never destroyed if immediately switched out and it has templateUrl. #9197

Closed
applegrew opened this issue Sep 21, 2014 · 6 comments
Assignees
Milestone

Comments

@applegrew
Copy link

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.

@lgalfaso
Copy link
Contributor

The issue is that the scope that the directive gets is already destroyed, in fact, it is already removed from the hierarchy

@lgalfaso
Copy link
Contributor

Let me take a deeper look into this issue

@lgalfaso
Copy link
Contributor

it looks like this is a bigger issue than expected

@caitp
Copy link
Contributor

caitp commented Sep 24, 2014

@petebacondarwin assigning this to you since it's basically the same as lucas' dupe (lets just close it when we land the fix)

@petebacondarwin petebacondarwin changed the title Directive scope is never destroyed if immediately switched out and it has templateUrl. SCOPE DESTRUCTION: Directive scope is never destroyed if immediately switched out and it has templateUrl. Sep 26, 2014
petebacondarwin added a commit to petebacondarwin/angular.js that referenced this issue Sep 29, 2014
Stop an asynchronous compilation when this is performed on an
already destroyed scope

Closes angular#9199
Closes angular#9079
Closes angular#8504
Closes angular#9197
petebacondarwin added a commit that referenced this issue Sep 29, 2014
Stop an asynchronous compilation when this is performed on an
already destroyed scope

Closes #9199
Closes #9079
Closes #8504
Closes #9197
@tiff
Copy link

tiff commented Oct 5, 2014

The Changelog says that this also made it into v1.2.26. I just downloaded it from angularjs.org and didn't find this change in it...

Edit: Probably because of this commit

@cztomsik
Copy link

+1

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants