AngularJS:指令作用域未调用$destroy
我在档案馆和网上搜索了一段时间寻找答案,但没有真正找到答案,只是零零碎碎的。似乎有很多建议的帖子,但没有一个有答案 我有一个使用scope的复杂指令:true。它实际上是我正试图为其编写清理代码的ng grid最新2.x版本,因为它正在疯狂地泄漏内存,而我们的应用程序目前正被它“卡住”。给你。当您单击网格并随后检查堆快照时,您将看到几个“未连接”的ngGrid对象。这些仅由指令作用域上的侦听器控制 当我通过单击多个网格(状态)来更改状态(使用ui.route latest)时,grid指令的作用域将获得$destroy事件。处理程序正在工作。但是,作用域本身没有被调用$destroy()。我在堆快照中看到,指令的作用域仍然通过$$listeners保留在元素上。此外,未设置作用域。$$destroyed 但是,scope.prototype已被销毁。正因为如此,我甚至不能从指令的$on-$destroy处理程序调用$scope.$destroy,因为proto的$destroy()调用将$destroy的定义更改为noop:AngularJS:指令作用域未调用$destroy,angularjs,angularjs-directive,scope,angularjs-scope,Angularjs,Angularjs Directive,Scope,Angularjs Scope,我在档案馆和网上搜索了一段时间寻找答案,但没有真正找到答案,只是零零碎碎的。似乎有很多建议的帖子,但没有一个有答案 我有一个使用scope的复杂指令:true。它实际上是我正试图为其编写清理代码的ng grid最新2.x版本,因为它正在疯狂地泄漏内存,而我们的应用程序目前正被它“卡住”。给你。当您单击网格并随后检查堆快照时,您将看到几个“未连接”的ngGrid对象。这些仅由指令作用域上的侦听器控制 当我通过单击多个网格(状态)来更改状态(使用ui.route latest)时,grid指令的作用
ngGridDirectives.directive('ngGrid', ['$compile', '$filter', '$templateCache', '$sortService', '$domUtilityService', '$utilityService', '$timeout', '$parse', '$http', '$q',
function($compile, $filter, $templateCache, sortService, domUtilityService, $utils, $timeout, $parse, $http, $q) {
var ngGridDirective = {
scope: true,
compile: function() {
return {
pre: function($scope, iElement, iAttrs) {
$(iElement).on('$destroy', function cleanupElementNgGrid() {
$timeout(function() {
$scope.$destroy();
$scope.destroyedByForce = true;
console.log("I destroyed it.");
},4000);
});
...
设置作用域。$$listeners={},$timeout为2000(为指令留出时间在我的on-$destroy listener中完成清理),这似乎是可行的,但使用内部构件感觉不太好,有时浏览器完成清理的时间不够长。这只是一个变通方法/kludge
我也试过:
那么,是什么阻止我的指令的作用域自动调用$destroy()
起初,我认为这是因为我们在指令选项中使用了scope:true,因为proto-scope似乎已被销毁。所以我写道。但通过这个plunk,指令的作用域已被正确销毁,没有对象泄漏。事实上,这非常令人惊讶。但我没有使用与第一个plunk中相同的视图嵌套;不过我怀疑没有就是这样。当视图发生变化时,控制器作用域仍然会被删除。我在一个内部对象上仍然有一个观察者。所以我想我会看到类似的动态。但是看起来$destroy确实在该内部作用域上被调用
关于什么会阻止指令作用域被调用$destroy(),有什么想法吗?它似乎与作用域有关:true位,但我不能完全解释为什么
提前谢谢大家,
杰西
更新:好的,我会发布这个问题的更新 尽我所能,似乎正在发生的事情是元素的主作用域(而不是grid指令的半隔离作用域)得到$destroy()d。但是,使用该作用域作为原型的子作用域很有可能提前退出$destroy方法,因为self.$$destrome是真的(原型继承).所以听众和观察家不会被清除 我可能会更新指令,使其在范围上完全隔离,但我没有时间去理清它的含义 我还发现它不仅仅是$destroy,$scope本身有很多函数,这些函数是由指令定义的,它围绕着内部变量形成闭包,这些变量包含大量内存 所以,我写了一个服务,提供额外的清理,很容易注入到有问题的grid指令中。我有一个plunk演示,但由于我的名声不好,我无法将其发布到主要部分:)。现在,您可以随意切换网格,但当前网格将保留在堆上 希望这有助于某人前进
我不知道这是否更适合作为评论。我最近在一个使用ng grid+angularjs的大型项目中工作,我们遇到了您遇到的所有问题:内存泄漏。我们发现并不是所有的东西都被很好地清理干净,示波器和手表到处都是
我们试图添加一些自定义逻辑来尝试做更好的清理,但并没有100%地解决我们的问题。ng grid上的水平滚动+虚拟化也突出了我们的问题,因此记住这一点可能也很有用(如果我没记错的话,他们计划在将来的版本中解决这个问题)。这里是指向显示上述解决方案的其他plunk的链接。您好,我有一个问题,我认为是相关的,您找到了$destroy没有在示波器上调用的原因吗?可能很有趣:本文讨论了$destroy链中由于子作用域的错误阴影而可能发生的中断(即:使用jquery)