Angular жизненные циклы компонентов селектора - ngoninit / ngondestroy / et c. срабатывают, если вложены один под другим. Можно ли избежать такого поведения? - PullRequest
0 голосов
/ 21 февраля 2020

Я создаю приложение, в котором у меня есть структура страницы примерно такая:

Объект, отрисованный из Firestore (размещенный элемент, как в Instagram)

  • Комментарии загружены ( взять идентификатор объекта выше для отображения подколлекции комментариев)
    • Ответы загружены (взять идентификатор объекта и комментария выше для отображения подколлекции ответов)

Здесь это то, что с точки зрения кода - упрощенная версия:

<div class="container">
  {{ object.data.text }}
  {{ object.data.likes.length }}
  <comment objectid="{{object.id}}">
</div>

Комментарий селектор

У меня есть такой шаблон - упрощенная версия:

<div *ngFor="let comment of comments | async" class="container">
  {{ comment.data.text }}
  {{ comment.data.likes.length }}
  <reply commentid="{{comment.id}}">
</div>

Ответы селектор

У меня есть такой шаблон - упрощенная версия:

<div *ngFor="let reply of replies | async" class="container">
  {{ comment.data.text }}
</div>

Выпуск: когда для объекта изменяется comment.data.likes.length, селектор ответов проходит полный жизненный цикл ngoninit и ngondestroy. Однако при изменении object.data.likes.length триггер жизненного цикла не происходит ни для комментариев, ни для селектора ответов. Конечный пользователь будет видеть, что ответы обновляются на внешнем интерфейсе каждый раз, когда кому-то нравится комментарий, что не является приятным опытом.

Кто-нибудь сталкивался с этой проблемой раньше или знает, как ее решить?

1 Ответ

2 голосов
/ 21 февраля 2020

Проблема здесь в том, что каждый раз, когда массив внутри *ngFor меняет свою ссылку, angular повторно рендерит все элементы снова, потому что он не может знать, какой элемент изменился, поэтому он удаляет все и возвращает обратно.

Что вам нужно сделать, это реализовать функцию trackBy, которая скажет Angular, как сравнивать объекты внутри for, и смотреть, изменились они или нет. Зная, что он сможет просто заменить элементы, которые изменились, вместо того, чтобы заменять все снова.

Итак, вместо

*ngFor="let comment of comments | async",

вам нужно:

*ngFor="let comment of comments | async; trackBy: myTrackByFn"

Где myTrackByFn - это функция, которую вы будете реализовывать в файле .ts:

myTrackByFn(index, item) {
    return item.id; // add the unique key for the item being iterated
}

Не забудьте реализовать эту функцию для всех три *ngFor у вас есть.

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