【发布时间】:2017-02-13 04:10:27
【问题描述】:
我想使用 javascript 动态创建 Angular 组件,然后使用 $compile 使用新创建的范围对它们进行 Angular 编译。然后当我不再使用该组件时,我想销毁该组件和新范围。
一切都按预期工作,除了即使我正在销毁新范围,它使用的所有内存都不会释放。
这是该代码的简化版本的一部分:
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);
};
}]);
此代码的完整工作示例是here
所有这些代码所做的,就是在每次单击按钮时创建一个新组件,但首先销毁任何已经存在的组件。 请注意,我实际上并没有在页面中添加已编译的组件,因为我注意到无论我是否使用它,泄漏仍然存在。
使用 Chrome 的开发工具(Profiles -> Record Allocation Timeline -> Start)点击按钮后我看到以下内存使用情况 几次:
很明显,customDirective 占用的任何内存都不会真正释放,即使正在调用作用域的$destroy 函数。
我过去成功地使用了$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();
});
};
}]);
【问题讨论】:
标签: javascript angularjs memory memory-leaks