3

Ng-if causing memory leak in angular js! Picture :https://www.mediafire.com/?ojoc55ccnyqlxyb

My app have two page

first page is homepage to show a input to search

second page is empy page to release memory .

How did I detected leak?
Run my app from link : http://www.mediafire.com/download/y5f6f326f3zo0ch/LeakProject_-_Copy.7z
use chrome in anonymus mode , F12 -> Profile -> Record Heap Allocation. You click on homepage after that click on emptypage and repeat more time , result is no any leak.

But if you type any thing to seach , after that you go to emptypage to release memory . you will get leak.

I found that , when go to empty page ,scope of ovNgListBox in homepage will destroy . I think that value of scope.textSearch will change to undefined and $scope.$watch in ng-if of angualr.js will execute to destroy scope. But something is vice versa: Although scope of html

<ov-ng-list-box class="ng-isolate-scope"><div ng-init="showFilter=true" class="pull-right">

is destroyed.

but scope of

 <input type="text" ng-model="textSearch" ng-if="showFilter" placeholder="please type here to search..." class="search ng-scope ng-pristine ng-valid">

is not destroyed . why why?

even if you to change value of scope.showFilter to false then $scope.$watch of in-if not called.

snippet code:

// templateleak.html <br/>

    <div class="pull-right" ng-init="showFilter=true" >
      <input type="text" class="search" placeholder="please type here to search..." ng-if="showFilter" ng-model="textSearch"/>
    </div>

// my directive
app.directive('ovNgListBox', [function () {
    return {
      restrict: 'AE',
      scope: {},
      templateUrl: 'views/template/templateLeak.html',
      controller: ['$scope',function(scope){
        console.log("Im in link of directive");
        scope.textSearch='';
        scope.search = function(){};
        scope.$on('$destroy', function(){
            scope.showFilter=false;
        });
      }]
    };
  }])


//angular.js
var ngIfDirective = ['$animate', function($animate) {
  return {
    transclude: 'element',
    priority: 600,
    terminal: true,
    restrict: 'A',
    $$tlb: true,
    link: function ($scope, $element, $attr, ctrl, $transclude) {
        var block, childScope, previousElements;
        $scope.$watch($attr.ngIf, function ngIfWatchAction(value) {

          if (toBoolean(value)) {
            if (!childScope) {
//
Qhai Nguyen
  • 41
  • 1
  • 4
  • 1
    @zeroflagL , please picture https://www.mediafire.com/?ojoc55ccnyqlxyb – Qhai Nguyen Sep 25 '14 at 04:56
  • I am actually facing the same issue, but wasn't sure if this is caused by ng-if. Thanks for finding out that ng-if is causing this, does the solution provided in the answer to your question works? I haven't tried it yet. – forestclown May 28 '15 at 03:15

1 Answers1

1

Use a cleanup function to clear the angular.element objects:

function dealoc(obj)
  {
  var jqCache = angular.element.cache;
  if (obj)
    {
    if (angular.isElement(obj))
      {
      cleanup(angular.element(obj));
      }
    else if (!window.jQuery)
      {
      // jQuery 2.x doesn't expose the cache storage.
      for (var key in jqCache)
        {
        var value = jqCache[key];
        if (value.data && value.data.$scope == obj)
          {
          delete jqCache[key];
          }
        }
      }
    }

  function cleanup(element)
    {
    element.off().removeData();
    if (window.jQuery)
      {
      // jQuery 2.x doesn't expose the cache storage; ensure all element data
      // is removed during its cleanup.
      jQuery.cleanData([element]);
      }
      // Note: We aren't using element.contents() here. Under jQuery,   element.contents() can fail
      // for IFRAME elements. jQuery explicitly uses (element.contentDocument ||
      // element.contentWindow.document) and both properties are null for IFRAMES that aren't attached
      // to a document.
var children = element[0].childNodes || [];
      for (var i = 0; i < children.length; i++)
        {
        cleanup(angular.element(children[i]));
        }
      }
    }

References

Community
  • 1
  • 1
Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265
  • Is this the suggested best practice when using ng-if? Also, when should dealoc be run? I've created a couple of jsFiddles to demonstrate the comparison with ng-show. ng-if - http://jsfiddle.net/neridum/hptt8wmu/, ng-show - http://jsfiddle.net/neridum/8vo7ae8L/ – Asta Apr 16 '15 at 14:47