kap*_*pou 8 javascript memory memory-leaks angularjs
我想使用javascript动态创建角度组件,然后使用$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);
};
}]);
Run Code Online (Sandbox Code Playgroud)
这个代码的完整工作示例在这里
所有这些代码都是在每次单击按钮时创建一个新组件,但首先销毁已存在的任何组件.请注意,我实际上并没有在页面中添加已编译的组件,因为我注意到无论是否使用它,泄漏仍然存在.
使用Chrome的开发工具(配置文件 - >记录分配时间轴 - >开始)我在点击按钮几次后看到以下内存使用情况:
很明显,即使$destroy调用了作用域的函数,customDirective占用的任何内存也从未实际释放过.
我已成功使用$compile过去而没有创建新的范围,但似乎我在这种情况下遗漏了一些东西.我是否应该做其他事情以确保没有对新范围的引用?
基于JoelCDoyle的下面的答案,这里是修复(我在我创建的范围上添加了一个销毁函数):
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();
});
};
}]);
Run Code Online (Sandbox Code Playgroud)
我想我已经找到了解决方案: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();
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
我仍然对它的工作原理有点模糊,但是角度编译文档中的指令如何编译这部分提供了线索: https: //docs.angularjs.org/guide/compiler
$compile 通过调用上一步中的组合链接函数将模板与范围链接起来。这反过来将调用各个指令的链接函数,在元素上注册侦听器并使用每个指令配置的范围设置 $watchs。\
其结果是范围和 DOM之间的实时绑定。因此,此时,编译范围内模型的更改将反映在 DOM 中。
我猜测,销毁作用域并不会删除这些元素侦听器。这就是上面的代码所做的:销毁指令/子范围 on 范围销毁
| 归档时间: |
|
| 查看次数: |
1505 次 |
| 最近记录: |