2014-06-24 83 views
2

我在嘗試手動編譯指令並通過JQuery將其添加到DOM。該指令是一個帶有ngClick處理程序的簡單div。在指令本身中沒有使用JQuery插件(這似乎是許多其他內存泄漏線程的焦點)。在Angular中手動編譯指令時發生內存泄露

如果你運行一個分析器,你會發現它泄漏節點。有沒有辦法解決這個問題,或者它是JQuery/Angular中的問題?

Fiddle here
Profiler screenshot

HTML

<div ng-app="TestApp"> 
    <buttons></buttons> 
    <div id="container"></div> 
</div> 

的Javascript

var ButtonsCtrl = function($scope, $compile) { 
    this.scope = $scope; 
    this.compile = $compile; 
}; 

ButtonsCtrl.prototype.toggle = function() { 
    var c = angular.element('#container').children(); 

    if (0 in c && c[0]) { 
     c.scope().$destroy(); 
     c.remove(); 
    } else { 
     var s = this.scope.$new(); 
     this.compile('<thing color="blue"></thing>')(s).appendTo('#container'); 
    } 
}; 

var ThingCtrl = function($scope) {}; 
ThingCtrl.prototype.clicky = function() { 
    alert('test'); 
}; 

var module = angular.module('components', []); 
module.directive('buttons', function() { 
    return { 
     restrict: 'E', 
     template: '<button ng-click="ctrl.toggle()">toggle</button>', 
     controller: ButtonsCtrl, 
     controllerAs: 'ctrl' 
    } 
}); 

module.directive('thing', function() { 
    return { 
     restrict: 'E', 
     scope: { 
      color: '@' 
     }, 
     template: '<div style="width:50px;height:50px;background:{{color}};" ng-click="ctrl.clicky()"></div>', 
     controller: ThingCtrl, 
     controllerAs: 'ctrl' 
    }; 
}); 

angular.module('TestApp', ['components']); 
+0

到底是什麼錯誤/泄漏?請編輯問題並將這些詳細信息放入。:-) – Shawn

+0

我已經提到它會泄漏節點。我更新了最初不正確的小提琴鏈接。 [點擊此處查看剖析器截圖](http://postimg.org/image/8rx18ln7n/) – willsters

回答

0

如果緩存模板功能$編譯的回報,然後調用以新的範疇,內存泄漏似乎每次點擊只會減少一個節點。

var ButtonsCtrl = function($scope, $compile) { 
    this.scope = $scope; 
    this.makeThing = $compile('<thing color="blue"></thing>'); 
    this.thingScope = null; 
}; 

此外,來自ButtonsCtrl.toggle()方法去除jQuery的包裝似乎完全消除節點泄漏。

ButtonsCtrl.prototype.toggle = function() { 
    var container = document.getElementById('container'); 

    if (this.thingScope) { 
     container.removeChild(container.childNodes[0]); 
     this.thingScope.$destroy(); 
     this.thingScope = null; 
    } else { 
     this.thingScope = this.scope.$new(); 
     container.appendChild(this.makeThing(this.thingScope)[0]); 
    } 
}; 

See what you think.

+0

最好在從DOM中刪除它之前銷燬子作用域 –