首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >AngularJs内存泄漏:即使被监视的元素被移除,作用域$$watchers也会增加

AngularJs内存泄漏:即使被监视的元素被移除,作用域$$watchers也会增加
EN

Stack Overflow用户
提问于 2015-03-17 00:33:12
回答 2查看 2.1K关注 0票数 4

我的AngularJs应用程序有个大问题.

我从服务器加载HTML内容(自定义表单)。当然,加载的HTML包含一些ng-showng-click等.

因此,在我的页面中追加之前,我会对其进行$compile。

效果很好。

但是,每次我$compile加载的HTML时,它都会在我的作用域中添加更多的$$watchers (当然是ng显示观察者)。

下面是一个演示/模拟:http://plnkr.co/edit/6sSazsFAugzE5XmcYkS7

我的问题是:如果在"load some“上单击数百次,$$watchers 不会减少内存泄漏。

我尝试过remove()empty()unbind()我的元素(链接),但是$$watchers数组一直在增长,从来没有被清理过。

我怎样才能解决这个问题?我如何清理无用的$$watchers或“未编译”?

谢谢你的帮助!

EN

回答 2

Stack Overflow用户

发布于 2015-03-17 01:01:36

因为新元素是从相同的作用域和相同的元素编译的,所以观察者永远不会被移除。

所有观察者在其作用域被破坏(scope.$destroy())时都会被移除,这在元素被删除时会自动发生。但是您的元素从未被移除,您可以继续用新节点替换它的HTML。

避免这种情况的一个明确方法是避免重新编译每一个新链接,而是生成一个动态的ng-repeat列表。

否则,如果希望保留代码,则可以在每次编译元素时为其创建一个新的作用域。这样,当重新编译它时,以前的作用域就会被销毁,所有的观察者都会被删除。

你可以在这里看到这一点。我所做的就是在编译调用中将scope替换为scope.$new(),以便每次都将新的作用域设置为元素:

http://plnkr.co/edit/PvUAYyb0IUoaT3dVmpGM?p=preview

PS:那是一个有趣的用例,虽然我从来没有遇到过,但它可以为这个角度的社区做出贡献:-)

票数 2
EN

Stack Overflow用户

发布于 2015-06-29 14:50:10

要正确销毁已编译元素的scope,需要执行scope.$destroy()。我建议的解决方案是创建一个继承的范围,然后销毁它:

代码语言:javascript
复制
    // if there was already an inherited scope, destroy it properly with $destroy()
    if (scope.inheritedScope) scope.inheritedScope.$destroy();
    // create new inherited scope every time 
    scope.inheritedScope = scope.$new(false);
    // use it in the compile
    $compile(element.contents())(scope.inheritedScope);

使用此解决方案的代码分叉:http://plnkr.co/edit/fOOHUGesbHYRiRWeLwKC

仅用element.html替换HTML并只执行scope.$new是不够的。我遇到了一个非常类似的情况,有一个更复杂的指令。一旦被替换,这个指令仍然会产生错误,所以我知道它仍然存在于内存中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29089388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档