ng-repeat如何工作?

时间:2013-11-21 22:40:10

标签: angularjs angularjs-ng-repeat

我解剖了ng-repeat并提取了附加的代码块,看到这些代码块包含处理重复算法的逻辑(我想了解它是如何工作的)。

我有很多问题,但由于它们都是关于ng-repeat的内部结构,所以我选择在这里问问他们。我认为没有理由将它们分成不同的SO问题。我已将每个问题引用的代码行标记为内联。

  1. 为什么他们需要确保trackById不是本地hasOwnProperty功能? (这是assertNotHasOwnProperty函数的作用,是Angular内部API的一部分)
  2. 就我的直觉而言,这段代码会对已经在转发器中的项目执行,当它必须更新集合时 - 它只是将它们选中并将它们推入列表进行处理,对吗?
  3. 此代码块显然会在转发器集合中查找重复项。但它究竟是如何做到这一点超出了我。请解释一下。
  4. 为什么Angular必须在nextBlockMap中存储nextBlockOrder 的块对象?
  5. 什么是block.endNodeblock.startNode
  6. 我认为上述问题的答案将阐明此算法的工作原理,但请解释为什么必须检查nextNode是否已经({1}}?
  7. 这里发生了什么?同样,我认为问题6已经为这一个提供了答案。但仍然指出了这一点。
  8. 就像我说的那样,我挖掘了ng-repeat以找到我认为与重复机制相关的代码。另外,我理解指令的其余部分。所以不用多说,这里是代码(来自v1.2.0):

    '$$NG_REMOVED'

1 个答案:

答案 0 :(得分:10)

在对指令进行一些修补之后,我熟悉了ng-repeater代码,并设法回答了我的一些问题。我在粗体中突出了我自己无法弄清楚的事情,如果有人能够对粗体部分有所了解,我会很感激:

  1. hasOwnProperty的ID进行了测试,因为他们使用该方法检查迭代对象(lastBlockMapnextBlockMap)中是否存在该ID(此过程如下所述)。 然而,我无法找到实际发生的情况。
  2. 我的假设是正确的。 nextBlockMap包含将在当前模型更改中转换的所有项目。 lastBlockMap包含先前模型更新中的所有内容。它用于在集合中查找重复项。
  3. 好的,这个实际上很简单。在此for循环中,ng-repeat使用nextBlockMap中的项目填充lastBlockMap。查看if的顺序,很容易看出,如果在lastBlockMap中找不到该项,但它已经存在于nextBlockMap中(意味着它已经从lastBlockMap复制了trackById,因此其forEach在集合中出现两次) - 它是重复的。 nextBlockMap执行的操作只需运行blockstartNode属性lastBlockMap属性)中的所有已初始化项目,然后将其ID 推回进入nextBlockOrder但我无法理解为什么这是必要的。
  4. 我可以找到将trackById(数组中的所有nextBlockMap)与blocktrackById哈希中的所有if (nextBlockOrder[index - 1]) previousNode = nextBlockOrder[index - 1].endNode;个对象分开的唯一原因),是这一行,使用数组使它变得简单易行:block.startNode。在问题5和6的答案中对此进行了解释:
  5. block.endNodepreviousNode是块中的第一个和最后一个DOM节点,属于所收集的项目中的重复项。因此,此行设置previousNode以引用转发器中上一项的最后一个DOM节点。
  6. $scope然后被用作第一个节点,在一个循环中检查当项目被移动或从转发器集合移除时DOM如何改变 - 再次,仅在我们不使用第一个时块中的块。
  7. 这很容易 - 它会初始化块 - 分配startNodeendNode以及nextBlockMap供以后参考,并将所有内容保存在endNode中。在克隆元素之后创建的注释是为了保证我们始终拥有{{1}}。