3

I have a directive that can trigger a bootstrap popover when I hover on it, I've noticed the $$watchers number increases every time after I hover on it, and it won't decrease even after the popover is removed, this is causing a memory leak in my application as this directive is in a list and doesn't get destroyed until user logs out. My question is how can I remove these watchers to prevent the memory leak?

This is the directive that can trigger the popover

  return module.directive('listItem', function () {
    return {
      restrict: 'E',
      replace: true,
      templateUrl: '/list-item.html',
      scope: {
        listItem: '='
      }
    };
  });

This is the list-item.html, my-popover is nothing but a ng bootstrap popover decorator.

<div class="list-item"
  my-popover 
  trigger="hover" 
  placement="bottom" 
  content-template="/list-item-popover.html">

This is list-item-popover.html

<div id="list-item-popover"> 
  <div id="saved-item-row">
      <i ng-class="listItem.examSaved ? 'icon-ico_star_sm' : 'icon-ico_starempty_sm' "></i>
    </span>
  </div>
</div>

As you can see above template has a ng-class, I saw a watcher is added to the $$watchers array under scope every time popover is displayed. After hovering over on it for 16 times, I saw 16 duplicate objects in the array. I am wondering if there is a way to prevent duplicate objects being added?

enter image description here

georgeawg
  • 48,608
  • 13
  • 72
  • 95
doranT
  • 167
  • 3
  • 11
  • 1
    What is the code for `my-popover`? – pgreen2 Mar 22 '17 at 04:14
  • 1
    `replace: true` is deprecated. See [Explain replace=true in Angular Directives (Deprecated)](http://stackoverflow.com/a/35519198/5535245). Specifically, the isolated scope of the `listItem` directive may be fighting the scopes of the other directives on the element. – georgeawg Mar 22 '17 at 07:42
  • Possible duplicate of [AngularJS Remove old $watchers when re-compiling dynamic html](http://stackoverflow.com/questions/42921937/angularjs-remove-old-watchers-when-re-compiling-dynamic-html) – georgeawg Mar 22 '17 at 11:10
  • @georgeawg, thanks for the info on replace: true. Regarding the scope fighting, my-popover shares the same scope of list-item. The other post you referred here is interesting, however, I have 2 directives in one element vs the post you referred only has 1 directive. I am wondering how I can make sure the my-popover is still working properly when recreating the new scope for list-item. – doranT Mar 22 '17 at 13:59
  • For the rules for sharing scope, see [AngularJS Comprehensive Directive API Reference - Scope](https://docs.angularjs.org/api/ng/service/$compile#-scope-). In general, the safest approach is to write directives with no scope but that takes more skill than writing directives with isolate scope. For popover directives, they should [append](https://docs.angularjs.org/api/ng/function/angular.element#angularjs-s-jqlite) an element and create a new child scope before compiling. Remove the element and $destory the scope when done. – georgeawg Mar 22 '17 at 21:38

0 Answers0