在新作用域下使用angular's $compile时发生内存泄漏
Memory leak when using angular's $compile with a new scope
我想使用javascript动态创建angular组件,然后让angular使用$compile
与新创建的作用域编译它们。然后,当我不再使用该组件时,我想要销毁该组件和新的作用域。
一切都像预期的那样工作,除了一个事实,即使我销毁了新的作用域,它所使用的所有内存都不会被释放。
下面是该代码的部分简化版本:
app.controller("mainCtrl", ["$scope", "$compile", function($scope, $compile) {
var childScope;
//call this every time the button is clicked
this.createDirective = function() {
//dynamically create a new instance of the custom directive
var customDirective = document.createElement("custom-directive");
//if another child scope exists, destroy it
if (childScope) {
childScope.$destroy();
childScope = undefined;
}
//create a new child scope
childScope = $scope.$new();
//compile the custom directive
$compile(customDirective)(childScope);
};
}]);
此代码的完整工作示例在这里
所有这些代码所做的,是每次点击按钮时创建一个新组件,但首先销毁任何已经存在的组件。请注意,我实际上并没有在页面中添加已编译的组件,因为我注意到无论我是否使用它,泄漏仍然存在。
使用Chrome的开发工具(配置文件->记录分配时间线->开始),我看到点击按钮后,以下内存使用情况几次:
内存消耗很明显,即使调用了作用域的$destroy
函数,customDirective所占用的任何内存也不会真正释放。
我过去成功地使用了$compile
而没有创建新的作用域,但似乎我在这种情况下缺少了一些东西。我是否还应该做一些其他的事情来确保没有对新作用域的引用?
根据下面JoelCDoyle的回答,这里是修复(我在我创建的作用域中添加了一个on destroy函数):
app.controller("mainCtrl", ["$scope", "$compile", function($scope, $compile) {
var childScope;
//call this every time the button is clicked
this.createDirective = function() {
//dynamically create a new instance of the custom directive
var customDirective = document.createElement("custom-directive");
//if another child scope exists, destroy it
if (childScope) {
childScope.$destroy();
childScope = undefined;
}
//create a new child scope
childScope = $scope.$new();
//compile the custom directive
var compiledElement = $compile(customDirective)(childScope);
//FIX: remove the angular element
childScope.$on("$destroy", function() {
compiledElement.remove();
});
};
}]);
固定小提琴标题>我想我已经找到了一个解决方案:https://jsfiddle.net/yqw1dk0w/8/
app.directive('customDirective', function(){
return {
template: '<div ng-controller="customDirectiveCtrl"></div>',
link: function(scope, element) {
scope.$on('$destroy', function() {
element.remove();
});
}
};
});
我仍然不太清楚为什么会这样,但是angular编译文档中的如何编译指令这一节提供了一个线索:https://docs.angularjs.org/guide/compiler
$compile通过调用组合函数将模板与作用域链接起来上一步中的链接函数。这反过来又会调用单个指令的链接函数,注册监听器在元素上设置$watch,并将作用域设置为each指令配置为do.'
这样做的结果是作用域和DOM之间的动态绑定。因此,在这一点上,在编译范围内的模型中的更改将反映在DOM中。
销毁作用域,我猜,不会删除这些元素侦听器。这就是上面代码所做的:destroy指令/子作用域上的作用域destroy
如果将数组放入作用域并取消分配,它将开始释放
$scope.array.length = 0;
到析构函数。但是…很高兴知道。我必须密切关注内存消耗。似乎保留了范围。因为我只是取消分配内部变量
- 错误:[$compile:nonassign]表达式'未定义'与指令'内容可编辑'是不可
- 重复应用 d3 转换导致的内存泄漏
- 在什么情况下需要同时使用compile&链接函数的角度
- IE7中的blockUI插件内存泄漏25kb
- Javascript闭包-如何防止内存泄漏
- 由于$compile,Javascript(Angular)嵌套指令加载了两次
- jQuery Draggable:内存泄漏
- 找不到容器:goog.Disposable.instances _在为javascript工具使用泄漏查找器时出错
- "检测到可能的EventEmitter内存泄漏”;使用Gulp+Watchify+Factor捆绑包
- 在Dojo类中递归调用setTimeout时是否存在内存泄漏
- 是内存泄漏
- 将处理程序留在img.onload上是内存泄漏
- 具有并发sse连接的node.js内存泄漏
- 简单对象的Javascript内存泄漏
- WeakMap是否会将我从父/子关系的内存泄漏中拯救出来
- Javascript绘制画布内存泄漏
- Node.js”;检测到EventEmitter内存泄漏”;
- 正在清理内存泄漏
- Angular$compile中的内存泄漏
- 在新作用域下使用angular's $compile时发生内存泄漏