在Angular中手动编译指令时内存泄漏

我正在尝试手动编译指令并通过JQuery将其添加到DOM。 该指令是一个带有ngClick处理程序的简单div。 指令本身没有使用JQuery插件(这似乎是许多其他内存泄漏线程的焦点)。

如果运行探查器,您会发现它泄漏了节点。 有没有什么可以解决这个问题或者它是JQuery / Angular中的问题?

在这里小提琴
Profiler截图

HTML

使用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('')(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: '', controller: ButtonsCtrl, controllerAs: 'ctrl' } }); module.directive('thing', function() { return { restrict: 'E', scope: { color: '@' }, template: '
', controller: ThingCtrl, controllerAs: 'ctrl' }; }); angular.module('TestApp', ['components']);

如果你缓存$ compile返回的模板函数,然后使用新的作用域调用它,内存泄漏似乎减少到每次点击只有一个节点。

 var ButtonsCtrl = function($scope, $compile) { this.scope = $scope; this.makeThing = $compile(''); 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]); } }; 

看看你的想法。