【问题标题】:Cannot read property '$$nextSibling' of null无法读取 null 的属性“$$nextSibling”
【发布时间】:2015-11-13 06:42:51
【问题描述】:

当我销毁自己的作用域时,我的程序中不断出现此错误。我在 angular 内追踪到这个 while 循环:

if (!(next = (current.$$childHead || (current !== target && current.$$nextSibling)))) {
    while(current !== target && !(next = current.$$nextSibling)) {
        current = current.$parent;
    }
}

我还设法在 jsFiddle 中复制了它:http://jsfiddle.net/kEyqz/1/

设置起来很容易,在一个元素上我连接一个点击事件,然后 $broadcast 它被点击,然后是一个 $apply。

在一个单独的指令(带有子作用域)中,我监听该事件,如果我看到它,我会销毁子​​作用域。这样做会产生错误:

Uncaught TypeError: Cannot read property '$$nextSibling' of null 

这只是我试图在我的代码中完成的一个小例子。

在 current = current.$parent 之前的控制台日志记录会导致范围没有 $parent(它设置为 null)。

我可以添加行:

if(!current){
    break;
}

在 current = current.$parent 之后,但如果我切换 angular 版本,我必须维护它(不理想)

【问题讨论】:

  • 似乎是一个已知的错误:github.com/angular/angular.js/issues/1627
  • 该错误在 9 个月前被标记为已修复,这个问题是关于当前 Angular 1.0.8 仍然存在的问题。
  • 您是否看到这个问题会破坏您自己创建的范围?您的 jsFiddle 中的示例正在破坏 Angular 为您的指令创建的范围。如果我将其更改为创建然后销毁不同的范围,我看不到这个问题。 jsfiddle.net/kEyqz/2
  • 问题与$broadcast 逻辑有关,因为该指令已被破坏,应通知DFS 算法忽略该指令节点。我认为您的修复没问题,您应该将其作为补丁提交。
  • 看看jsfiddle.net/kEyqz/7,是你想要的吗?

标签: angularjs


【解决方案1】:

这就是你要找的http://jsfiddle.net/jw99Lj7t/ 吗?

你在 $destroy'ing $scope durgin digest 循环 - 这是导致错误的原因。

我不相信这是一个bug,因为这就是digest 循环的实现方式(它循环遍历$scopes 的列表,检查是否发生了变化,我们无法从中删除范围该列表“已在使用”)。

解决此问题可能会带来很多复杂性,而且由于digest 必须非常快,因此最好为您正在做的事情找到不同的方法。

【讨论】:

  • 这是最后的手段。我目前已经将那段代码作为故障保护。
  • @MathewBerg 最后的案例,我想你会发现这是唯一的方法,我多次遇到这个错误,实际问题是你已经破坏了范围,但角度仍然存在使用该范围并认为它仍然存在,因此对其进行检查。 setTimeout 是唯一的方法,它可以确保在销毁范围之前完成 angular。 @g00fy 在您的演示中您正在使用 setTimeout 但您没有在代码中的任何地方提及它,如果您这样做了,+1
  • 我的解决方案使用 $timeout 代替,但基本上是一样的。
  • @MathewBerg 你为什么要使用$timeout?那是为了设置一个超时,在这个超时内你想使用范围,当你不这样做时,你不想破坏它。
  • 使用 setTimeout 方法,如果其他东西正在监听该范围以被销毁,您需要在之后运行 $apply() 。通过将它包装在 $timeout 中,我只是确保它发生在周期的后期,即广播完成之后(问题所在)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-29
  • 2016-11-24
  • 2012-04-29
  • 2019-01-07
相关资源
最近更新 更多