(为什么)有一个“自称”的指令在一个有限的n -repeat导致一个堆栈溢出从无限递归

(Why) does having a directive that "calls itself" in a finite ng-repeat lead to a stack overflow from infinite recursion?

本文关键字:一个 -repeat 堆栈 栈溢出 递归 无限 指令 自称 有一个 为什么      更新时间:2023-09-26

编辑:查看这个问题的简化版本(一个sscce)


下面的代码似乎会导致无限递归问题:

statement.directive.html

<textarea></textarea><br />
<button ng-click='statement.newStatement()'>New Statement</button>
<button ng-click='statement.newSubstatement()'>New Substatement</button>
<hr />
<statement
  ng-repeat='statement in statement.curr.sections'
  curr='statement'
  parent='statement.curr'>
</statement>

我不知道为什么。statement.curr.sections是零(当我测试它时)。那么指令不会"实例化/实现"吗?


<p ng-repeat='statement.curr.sections'>x</p>

不会引起任何问题。

将其包装在ng-if中并不能解决问题。

<div ng-if='statement.curr.sections > 0'>
  <statement
    ng-repeat='statement in statement.curr.sections'
    curr='statement'
    parent='statement.curr'>
  </statement>
</div>

编辑:这也不起作用(但我意识到我选择了糟糕的变量名)。

<textarea></textarea><br />
<hr />
<statement
  ng-repeat='item in statementCtrl.curr.sections'>
</statement>
GitHub上的代码

我看了一下你的github代码,但它真的很令人困惑。这个名字让我的脑子一片混乱,所以我想先澄清一下。

对于一个指令,你应该使用一个前缀,这样就可以清楚地看到你引用了一个指令。myStatements, elStatement,等等

对于服务和控制器,使用后缀:StatementService, StatementController。

我不明白的地方:

<button ng-click='statement.newStatement()'>New Statement</button>

这里statement.指的是什么?什么时候初始化/绑定到视图?编辑:没关系,我看到那是控制器。

好了,你已经有了指令的模板,引用了指令本身…

嗯,不确定一个指令是否可以有一个子指令,那就是它自己。当模板试图渲染时,似乎是无限循环。因为即使下一个层/指令没有数据,它仍然需要引导指令和它的模板,这样就会导致它加载下一个指令…它永远不会结束。

似乎是一个反模式。用例是什么?你是想画一个分形吗?lol

对于分形来说,你需要通过一个极限(即。当一个分形变得非常小,你看不到它,就不再有一个点来画它)。因此,通过施加一些限制,你可以阻止它无限地尝试绘制。

tl;dr:即使数据为空,子指令仍在初始化/呈现