我解剖了ng-repeat并提取了附加的代码块,看到这些代码块包含处理重复算法的逻辑(我想了解它是如何工作的)。
我有很多问题,但由于它们都是关于ng-repeat的内部结构,所以我选择在这里问问他们。我认为没有理由将它们分成不同的SO问题。我已将每个问题引用的代码行标记为内联。
trackById
不是本地hasOwnProperty
功能? (这是assertNotHasOwnProperty
函数的作用,是Angular内部API的一部分)nextBlockMap
中存储nextBlockOrder
和的块对象? block.endNode
和block.startNode
?nextNode
是否已经({1}}?就像我说的那样,我挖掘了ng-repeat以找到我认为与重复机制相关的代码。另外,我理解指令的其余部分。所以不用多说,这里是代码(来自v1.2.0):
'$$NG_REMOVED'
答案 0 :(得分:10)
在对指令进行一些修补之后,我熟悉了ng-repeater
代码,并设法回答了我的一些问题。我在粗体中突出了我自己无法弄清楚的事情,如果有人能够对粗体部分有所了解,我会很感激:
hasOwnProperty
的ID进行了测试,因为他们使用该方法检查迭代对象(lastBlockMap
,nextBlockMap
)中是否存在该ID(此过程如下所述)。 然而,我无法找到实际发生的情况。 nextBlockMap
包含将在当前模型更改中转换的所有项目。 lastBlockMap
包含先前模型更新中的所有内容。它用于在集合中查找重复项。for
循环中,ng-repeat
使用nextBlockMap
中的项目填充lastBlockMap
。查看if
的顺序,很容易看出,如果在lastBlockMap
中找不到该项,但它已经存在于nextBlockMap
中(意味着它已经从lastBlockMap
复制了trackById
,因此其forEach
在集合中出现两次) - 它是重复的。 nextBlockMap
执行的操作只需运行block
(startNode
属性lastBlockMap
属性)中的所有已初始化项目,然后将其ID 推回进入nextBlockOrder
。 但我无法理解为什么这是必要的。 trackById
(数组中的所有nextBlockMap
)与block
(trackById
哈希中的所有if (nextBlockOrder[index - 1]) previousNode = nextBlockOrder[index - 1].endNode;
个对象分开的唯一原因),是这一行,使用数组使它变得简单易行:block.startNode
。在问题5和6的答案中对此进行了解释:block.endNode
和previousNode
是块中的第一个和最后一个DOM节点,属于所收集的项目中的重复项。因此,此行设置previousNode
以引用转发器中上一项的最后一个DOM节点。$scope
然后被用作第一个节点,在一个循环中检查当项目被移动或从转发器集合移除时DOM如何改变 - 再次,仅在我们不使用第一个时块中的块。startNode
和endNode
以及nextBlockMap
供以后参考,并将所有内容保存在endNode
中。在克隆元素之后创建的注释是为了保证我们始终拥有{{1}}。