我正在尝试手动编译指令并通过JQuery将其添加到DOM中。该指令是一个带有ngClick处理程序的简单div。指令本身没有使用JQuery插件(这似乎是许多其他内存泄漏线程的焦点)。
如果您运行探查器,您会发现它泄漏了节点。有没有什么可以解决这个问题或者它是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 :(得分:0)
如果你缓存$ 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');
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]);
}
};