在 Angular 中手动编译指令时出现内存泄漏 [英] Memory leak when manually compiling directives in Angular
问题描述
我正在尝试手动编译指令并通过 JQuery 将其添加到 DOM.该指令是一个带有 ngClick 处理程序的简单 div.指令本身没有使用 JQuery 插件(这似乎是许多其他内存泄漏线程的焦点).
如果您运行分析器,您会发现它会泄漏节点.有什么办法可以解决这个问题,还是 JQuery/Angular 中的一个问题?
HTML
<按钮></按钮><div id="容器"></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();} 别的 {var s = this.scope.$new();this.compile('<thing color="blue"></thing>')(s).appendTo('#container');}};var ThingCtrl = function($scope) {};ThingCtrl.prototype.clicky = function() {警报('测试');};var module = angular.module('components', []);module.directive('buttons', function() {返回 {限制:'E',模板:'<button ng-click="ctrl.toggle()">toggle</button>',控制器:ButtonsCtrl,控制器为:'ctrl'}});module.directive('东西', function() {返回 {限制:'E',范围: {颜色: '@'},模板:'<div style="width:50px;height:50px;background:{{color}};"ng-click="ctrl.clicky()"></div>',控制器:ThingCtrl,控制器为:'ctrl'};});angular.module('TestApp', ['components']);
如果你缓存 $compile 返回的模板函数,然后用新的作用域调用它,内存泄漏似乎减少到每次点击只有一个节点.
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');如果(this.thingScope){container.removeChild(container.childNodes[0]);this.thingScope.$destroy();this.thingScope = null;} 别的 {this.thingScope = this.scope.$new();container.appendChild(this.makeThing(this.thingScope)[0]);}};
I'm trying to manually compile a directive and add it to the DOM via JQuery. The directive is a simple div with an ngClick handler. No JQuery plugins are used in the directive itself (which seems to be the focus of many of the other memory leak threads).
If you run a profiler you will find that it leaks nodes. Is there something that can be done to fix this or is it a problem in 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']);
If you cache the template function that $compile returns, then call that with a new scope, the memory leak seems to decrease to only one node per click.
var ButtonsCtrl = function($scope, $compile) {
this.scope = $scope;
this.makeThing = $compile('<thing color="blue"></thing>');
this.thingScope = null;
};
Additionally, removing the jQuery wrappers from the ButtonsCtrl.toggle() method appears to eliminate the node leak altogether.
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]);
}
};
这篇关于在 Angular 中手动编译指令时出现内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!