Как директива Angular2 + ngFor выполняет итерации по итерации? - PullRequest
0 голосов
/ 21 декабря 2018

Я пытаюсь понять, как директива Angular *ngFor работает за кулисами.Что-то, что я хотел знать, было ли интерпретируемая передаваемая в директиву итерация интерпретировалась на каждой итерации цикла (например, условие цикла JS for) или angular создает переменную, похожую на «кеш» с этим значением.Чтобы ответить на этот вопрос, я сделал 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 просто вызывает методна каждой итерации.Но это то, где это начинает быть сложным для меня ...

Затем я попытался изменить массив ссылок dataArr, используемый методом, добавив в него некоторые другие значения, например:

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

Но теперь у меня все еще есть 4 итерации в консоли ... Затем я попытался с

dataArr = [1,2];

и еще 4 итерациями booom ...

Так что теперь я очень озадаченэто ... Почему у меня всегда 4 итерации?Первой попыткой была просто удача выбрать 4 элемента в моем массиве, и на самом деле это не имеет к этому никакого отношения?Я попытался взглянуть на угловой исходный код ngfor, но я все еще не тот ниндзя, который понимает это без объяснений ...

Спасибо

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

Вот еще немного о том, что такое итератор.Массив является итератором, но он неявный, автоматический, вы его не видите.Вы рассчитываете не то, сколько раз вещь была повторена, а , сколько раз ваша функция вызывается .

Если вы хотите отслеживать, сколько итераций у вас уже есть, вы должны создать собственный итератор.Итератору нужно возвращать метод next(), который вызывается столько раз, сколько у вас есть значений для возврата.То, что вы возвращаете из этого next(), является объектом с { value, done } подписью - value является чем угодно, и done является истинным, когда вы закончите.Именно внутри этого next вы можете сосчитать количество итераций.

Вот пример рядом с вашим кодом.

Что делает движок JavaScript, так это то, что он делаетмассивы итерируются неявно.

0 голосов
/ 21 декабря 2018

Отлично, я вижу, что angular просто вызывает метод на каждой итерации.Но это то, где это начинает быть сложным для меня ...

Вы не видите итераций.Angular вызывал метод каждый раз, когда отображался DOM.Это не имеет никакого отношения к тому, сколько элементов было в массиве.Просто по счастливой случайности вы увидели, что это число равно 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 нужно только назначить источник итератор один раз за проход рендеринга.В вашем выражении функция test() возвращает итератор (который является массивом).Он возьмет значение next () из итератора и присвоит его переменной data, которая будет отображаться в шаблоне.

ngFor будет продолжать вызывать next () пока не достигнет конца итератора.Для каждой итерации ngFor проверяет, есть ли элемент DOM, который должен быть вставлен, обновлен или удален.Он знает, какие данные поступают с каким DOM-элементом, используя функцию trackBy .

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...