系统相关
首页 > 系统相关> > javascript – 使用$scope.$destroy解决了内存泄漏问题但违反了指令

javascript – 使用$scope.$destroy解决了内存泄漏问题但违反了指令

作者:互联网

我有一个子指令,它在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函数运行后它会按预期显示.

这里的问题是我需要能够根据父级页面上的其他活动添加更多这些子指令.在这个destroy活动之后,我发现当我第二次重新执行这个过程时,范围没有很好地加载 – 相反,我看到现在为child指令创建了一些范围,但我发现有些绑定不再更新(例如,我注意到当子指令中的范围值发生变化时,ng-hide不再更新),因此指令最终无法使用.

一般来说,我假设逻辑中只有一个错误,我需要去寻找它并且可能很好,除了在调试这个时,我发现在那个处理销毁子指令的父函数中,如果我注释掉这条线:

elem.scope().$destroy();

所有的范围都保留在Batarang中,所有的DOM元素都会像你期望的那样消失,所以这看起来像是一个内存泄漏,除非我运行触发器使命令再次加载,它们加载时没有问题(我现在结束了Batarang视图中的许多范围,现在从未清除过).

什么会导致这种行为,因为$销毁指令的隔离范围会破坏指令的未来使用,但是留下它会让它在以后工作,但会导致内存泄漏?是否有另一种方法可以在不使用$destroy的情况下清除这些范围?

编辑:
经过进一步调查,我发现当第一个指令被创建时,它有一个适当创建的隔离范围,但是在制作后续指令时,它们的隔离范围是在Batarang中创建的,但是如果我实际使用angular.element进行查找(‘lookup-their-individual-idents’).scope()报告的ID实际上是父级的ID,因此当我破坏第一个时,它会按预期清理.当我销毁第二个时,它实际上消灭了父范围(以及所有孩子),所以这就是为什么它没有准确地放在父母的前进上.

因此,我希望我只需要弄清楚当我将它们添加到DOM时如何将隔离的范围适当地绑定到指令,其余的将自行解决.

解决方法:

一旦我开始查看究竟哪些指令在Batarang中被创建和销毁时,问题就变得明显了.如果第一个指令始终具有隔离范围,则后续指令都不会,而且它们都将继承父范围,因此当它们全部被销毁时,父范围将与它们一起使用.

相反,虽然上面显示的代码用于创建页面上没有任何内容的新指令,但我需要更新实际负责在该父指令中将多个指令放在页面上以使其创建隔离范围的代码对于每个新孩子,例如:

var child = this.templateGenerator.addChild(applicableData);
var compiledChild = this.$compile(child)(scope.$new(true));
element.append(compiledChild);

现在,如果我查看每个指令,他们都指向Batarang的预期范围.更重要的是,当我销毁它们并在页面上放置新指令时,它们也按预期加载,因此这解决了问题.

标签:javascript,angularjs,angular-directive
来源: https://codeday.me/bug/20190623/1270992.html