Angular2 + ngFor指令如何遍历ref可迭代?

时间:2018-12-21 14:44:05

标签: angular loops ngfor angular2-changedetection

我尝试了解Angular的*ngFor指令在后台如何工作。 我想知道的是,传递给指令的可迭代对象是否在每次循环迭代时都得到了解释(例如JS for循环的条件),或者angular是否使用该值创建了类似于“ cache”的变量。为了回答这个问题,我做了一个ngFor,它有一个返回数组作为可迭代对象的方法。

<li *ngFor="let data of test(dataArr)">{{data}}</li>

相关的TS:

 dataArr = [1,2,3,4];
 iterationNb = 1;
 test(arr) {
    console.log('has iterated', this.iterationNb++);
    return arr.filter(i => true);
 }

这是我在控制台中看到的内容:

has iterated 1
has iterated 2
has iterated 3
has iterated 4

如果您需要角度项目,这是我的试用版示例应用程序:https://stackblitz.com/edit/angular-3kmyyw

那太好了,我看到angular每次迭代都调用该方法。但这对我来说变得很复杂...

然后,我尝试通过在其中添加一些其他值来更改该方法使用的ref数组dataArr

dataArr = [1,2,3,4,5,6,7];

但是现在我的控制台中仍然有4次迭代... 然后我尝试了

dataArr = [1,2];

并且仍然弹出4次迭代...

所以现在我对此非常困惑... 为什么我总是4次迭代?第一次尝试只是幸运地选择了我数组中的4个项目,实际上与之无关吗? 我试图看一下有角度的ngfor源代码,但我仍然不是没有解释就可以理解它的忍者...

谢谢

2 个答案:

答案 0 :(得分:4)

  

那太好了,我看到angular每次迭代都调用该方法。但这对我来说变得很复杂...

您没有看到迭代。每次渲染DOM时,Angular都会调用该方法。它与数组中有多少个元素无关。幸运的是,您看到它的数量为4。

<li *ngFor="let data of test(dataArr)">

以上操作每渲染一次执行一次。 *ngFor指令将表达式分为两个变量。对 current 迭代器的引用,以及对源 iterator 的引用。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Iterators

ngFor仅需要为每个渲染过程分配一次源 iterator 。在您的表达式中,test()函数返回迭代器(恰好是一个数组)。它将从迭代器中获取 next()值,并将其分配给将在模板中公开的data变量。

ngFor将继续调用 next(),直到到达迭代器的末尾。对于每次迭代,ngFor检查是否应插入,更新或删除DOM元素。它使用 trackBy 函数知道哪些数据与哪个DOM元素一起使用。

https://medium.com/@ramy_ali/improving-angular-ngfor-performance-through-trackby-ae4cf943b878

答案 1 :(得分:0)

关于什么是迭代器还有更多内容。数组是迭代器,但它是隐式的,自动的,您看不到它。您所计算的不是事物被迭代多少次,而是函数被调用多少次

如果要跟踪已拥有的个迭代,则必须构建一个自定义迭代器。迭代器需要返回一个next()方法,该方法被调用的次数与要返回的值一样多。您从此next()返回的结果是一个带有{ value, done }签名的对象-value是任意的,完成后done为真。您可以在此next内部计算迭代次数。

Here's代码旁边的示例。

JavaScript引擎的作用是使隐式使数组可迭代。