gpt4 book ai didi

javascript - 使用 $scope.$destroy 解决内存泄漏但破坏指令

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:43:39 31 4
gpt4 key购买 nike

我有一个在 TypeScript AngularJS 应用程序中动态运行的子指令。模板和 Controller 在运行时根据给定情况需要执行的操作进行附加,并且模板本身包含许多指令。我需要能够在页面上显示多个指令,因此我在每个指令之间使用了一个独立的范围。我有另一个指令负责跟踪这些子指令中的哪些应该在任何给定时间出现在页面上(称为父指令)。

如果我需要添加一个新的子元素,我会在那个父指令中为它创建模板,确定我想要附加它的元素并使用:

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 事件之后,我发现当我第二次重新执行这个过程时,范围没有完全正确地加载 - 相反,我现在看到了为子指令创建的一些范围,但我发现其中一些绑定(bind)不再更新(例如,我注意到当子指令中的范围值发生变化时,ng-hide 不再更新)因此该指令最终无法使用。

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

elem.scope().$destroy();

所有范围都保留在 Batarang 中,所有 DOM 元素都如您所料消失,所以这看起来有点内存泄漏,除非我运行触发器使指令再次加载,它们会加载没有问题(现在我只是在 Batarang View 中看到许多范围,这些范围永远不会清除)。

什么会导致这种行为,因为 $destroying 指令的独立作用域会破坏指令的 future 使用,但是将它留在那里使其稍后可以工作,但会导致内存泄漏?是否有另一种方法可以在不使用 $destroy 的情况下清除这些作用域?

编辑:经过进一步调查,我发现当第一个指令被创建时,它有一个适当创建的隔离范围,但是在制作后续指令时,它们的隔离范围是在 Batarang 中创建的,但如果我真的用 angular.element 进行查找('lookup-their-individual-idents').scope() 报告的 ID 实际上是父 ID,因此当我销毁第一个时,它会按预期进行清​​理。当我销毁第二个时,它实际上会清除父作用域(以及所有子作用域),所以这就是为什么它不能准确地放置在父作用域上的原因。

因此,我希望在将独立作用域添加到 DOM 时,我只需要弄清楚如何将它们适本地绑定(bind)到指令,其余的将自行解析。

最佳答案

当我开始查看在 Batarang 中究竟创建和销毁了哪些指令时,问题就变得很明显了。第一个指令总是有一个独立的作用域,而后续指令都不会,而是它们都会继承父作用域,因此当它们全部被销毁时,父作用域将随之消失。

相反,虽然我上面显示的代码用于创建页面上没有的新指令,但我需要更新实际负责在该父指令中的页面上放置多个指令的代码以使其创建每个新 child 的独立范围,例如:

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

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

关于javascript - 使用 $scope.$destroy 解决内存泄漏但破坏指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34367488/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com