Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AngularJS:指令作用域未调用$destroy_Angularjs_Angularjs Directive_Scope_Angularjs Scope - Fatal编程技术网

AngularJS:指令作用域未调用$destroy

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指令的作用

我在档案馆和网上搜索了一段时间寻找答案,但没有真正找到答案,只是零零碎碎的。似乎有很多建议的帖子,但没有一个有答案

我有一个使用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:

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)