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) {
//
2
  • 1
    @zeroflagL , please picture mediafire.com/?ojoc55ccnyqlxyb Commented Sep 25, 2014 at 4: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. Commented May 28, 2015 at 3:15

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

1 Comment

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 - jsfiddle.net/neridum/hptt8wmu, ng-show - jsfiddle.net/neridum/8vo7ae8L

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.