使用$scope$destroy解决了内存泄漏,但破坏了指令
Using $scope.$destroy solves memory leak but breaks directive
我有一个在TypeScript AngularJS应用程序中动态运行的子指令。模板和控制器在运行时根据它在给定情况下需要做的事情进行附加,模板本身包含许多指令。我需要能够在页面上显示多个指令,所以我在每个指令之间使用一个隔离的范围。我有另一个指令,负责跟踪这些子指令中的哪一个应该在任何给定时间出现在页面上(称为父指令)。
如果我需要添加一个新的子项,我会在父指令中为其创建模板,确定要将其附加到的元素并使用:
var compiledDirective = this.$compile(myTemplate)(scope.$new(true, scope));
angular.element(".parent").append(compiledDirective);
_.defer(() => {
scope.$apply();
});
如果我加载应用程序,这会很好地工作,我可以看到它创建了每个按我期望运行的子级。当我需要删除任何/所有这些子级时,这个父级也可以在以下函数中处理:
var destroyChild = (identifier: string) {
this.$timeout(() => {
var elem = angular.element(".parent").find(`li[ident='${identifier}']`);
elem.scope().$destroy();
elem.remove();
_.defer(() => {
});
});
}
现在,所有元素都会按预期自行删除,如果我查看Batarang,我会看到指令从可用范围中消失。我在子指令中有一个$destroy事件的事件处理程序,所以当指令被销毁时,我可以看到一条控制台消息,并且在这个destroy函数运行后,它会按预期显示。
这里的问题是,我需要能够基于父级中页面上的其他活动添加更多的这些子指令。在这个销毁活动之后,我发现当我第二次重新执行这个过程时,作用域加载不太正确——相反,我现在看到了为子指令创建的许多作用域,但我发现一些绑定不再更新(例如,当子指令中的作用域值发生变化时,我注意到ng隐藏不再更新),因此该指令最终不可用。
一般来说,我会假设逻辑中有一个错误,我需要去寻找它,很可能会有,只是在调试时,我发现在处理销毁子指令的父函数中,如果我注释掉这一行:
elem.scope().$destroy();
所有作用域都保留在Batarang中,所有DOM元素都如您所料消失了,所以这看起来有点像内存泄漏,只是如果我运行触发器使指令再次加载,它们加载时不会出现问题(我只是在Bataraang视图中发现了许多作用域,但这些作用域永远不会清除)。
是什么导致了这种行为,因为$破坏指令的隔离作用域会破坏指令的未来使用,但将其留在那里会使其稍后工作,但会导致内存泄漏?有没有其他方法可以在不使用$destroy的情况下清除这些作用域?
编辑:经过进一步的调查,我发现当创建第一个指令时,它有一个适当创建的隔离作用域,但在生成后续指令时,它们的隔离作用区是在巴塔朗中创建的,但如果我真的用angular.element('lookuptheir-individeal-idents').scope()进行查找,则报告的ID实际上是父级的ID,所以当我销毁第一个时,它会像预期的那样清理干净。当我销毁第二个时,它实际上会删除父作用域(从而删除所有子作用域),所以这就是为什么它没有准确地放置在父作用域上的原因。
因此,当我将隔离的作用域添加到DOM时,我希望我只需要弄清楚如何将它们适当地绑定到指令,其余的将自行解决。
当我开始查看哪些指令在巴塔朗中被创建和销毁时,这个问题就变得很明显了。如果第一个指令总是有一个孤立的作用域,那么后面的指令都不会继承父作用域,相反,它们都继承了父作用域。所以当它们都被销毁时,父作用域就会随之而去。
相反,虽然我上面显示的代码用于创建页面上没有的新指令,但我需要更新实际负责在父指令中的页面上放置多个指令的代码,使其为每个新子指令创建独立的范围,例如:
var child = this.templateGenerator.addChild(applicableData);
var compiledChild = this.$compile(child)(scope.$new(true));
element.append(compiledChild);
现在,如果我看一下每一条指令,它们都指向巴塔朗的预期范围。更重要的是,当我销毁它们并在页面上放置新指令时,它们也会按预期加载,因此这解决了问题。
- "工具提示"jQuery插件坏了
- 我的按钮坏了
- 节点JS:时间机器坏了——timekeeper.travel不做时间旅行
- HTML/JavaScript:为什么不'我的纽扣坏了
- 我的素数函数坏了,但我没有;我不知道为什么
- Uglifier是不是弄坏了我的睡衣
- 我升级了Knockout.js,现在我的模板坏了
- 为什么范围$手表坏了
- 所有的javascript都 ajax.aspnetcdn.com/ajax/ 坏了?打破所有外部引用?自周五以来
- 角度控制器功能坏了
- 谷歌可视化图表API示例坏了,如何修复它们
- 检查是否传递了指令属性
- 将Facebook应用程序移动到新服务器,现在它坏了
- 为什么我的代码坏了
- 野生动物园浏览器中的后退按钮坏了
- 砌体坏了(可能是经典)
- 旋转相机后,Three.js的skybox似乎坏了
- 角度模型放宽了指令中包含ng的范围
- 使用$scope$destroy解决了内存泄漏,但破坏了指令
- 验证不是't工作,现在我的网站也坏了