Angular ngIf意外行为

时间:2014-07-08 15:08:01

标签: angularjs google-chrome chromium

我有一个名为myForm的简单HTML表单。其中一个表单字段包含ng-if="true"

console.log(myForm)表示该表单是一个包含5个项目的数组。 console.log(myForm.length)返回数字4.

请参阅示例 http://plnkr.co/edit/MHi6FpEs9l0wbC96Cx6b?p=preview

1 个答案:

答案 0 :(得分:3)

最近这也让我感到兴奋,在稍微调查之后我认为问题是ng-if设置了$watch in its link function,所以即使你的指令的链接功能可以在ng-if之后执行, $watch只有在下一个$digest之后才会被触发(或者在同一个$watch之后才会被触发?不完全确定。

因此,两个指令都被编译,然后链接,最后触发$timeout并插入ng-if DOM元素。

如果您将代码包装在$digest中,它将反映正确的值,因为<!-- ngIf: true -->将完成:

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

控制台将窗体长度显示为4的原因是因为当你的指令链接函数运行时,编译了ng-if,从DOM中删除了你的输入,replaces it with a comment看起来像{{1}但是,ng-if链接功能中声明的$watch尚未运行。

ng-if等待$watch,然后将输入的克隆添加回DOM ,如果 $watch表达式为但是,由于它在链接函数时没有运行且注释不是有效的表单输入,因此表单长度为4。

如果我理解正确的事件顺序:

  1. ng-if编译(删除输入并将其替换为注释,表单长度为4)
  2. 你的指令编译
  3. ng-if linking
  4. 您的指令链接(仍然没有输入,表单长度仍为4)&lt; - 这里是您设置scope.formLength
  5. 的地方
  6. ng-if $ watch(如果表达式为真,表单长度为5,则添加输入克隆)

  7. Form.length返回4,尽管仍有5个元素,因为根据规范,form.length returns the length of the elements array,其中包括button, fieldset, input, keygen, object, output, select, and textarea但不包括div:)


    console.log显示长度为4的原因,但是5个有效输入是因为您传入了对表单元素的引用。至少在Chrome中,传递给console.log的对象的即时快照以斜体显示,但是当您单击以在控制台中展开对象时,将显示引用的当前对象,这就是表单显示为有5个有效输入。不幸的是the snapshot in italics is condensed,所以你无法从console.log中看到表单只有4个输入。

    如果您在console.log时克隆输入,则可以看到它实际上没有第5个输入。

    var myFormClone = myForm.cloneNode(true);
    console.log(myForm) //has 5 inputs by the time you see it
    console.log(myFormClone) //has 4 inputs
    

    相关铬问题:https://code.google.com/p/chromium/issues/detail?id=50316