Будет ли компонент обновлен при следующем Change Detection, если вызвать markForCheck на нем в Angular?
Что проверяют
Понимаете ли вы, что markForCheck() сам ничего не перерисовывает, а только помечает вид для следующей проверки, и в какую сторону по дереву идёт эта пометка. Следом обычно спрашивают разницу с detectChanges() и как всё работает в zoneless-приложении и с сигналами.
Как отвечать
Короткий ответ: да, будет, если следующая проверка изменений вообще запустится и компонент не отсоединён от дерева через detach().
Дальше механика:
- что делает:
ChangeDetectorRef.markForCheck()помечает текущий вид и всех его предков до корня как требующие проверки. Это нужно дляOnPush: такой компонент при обходе пропускается, пока не помечен, не получил новую ссылку во входе или не обработал событие из своего шаблона; - когда срабатывает: сам вызов цикл не запускает. С zone.js проверку запустит следующая асинхронная задача в зоне, в zoneless-режиме
markForCheck()уведомляет планировщик Angular и тот ставит проверку в очередь; - вниз не идёт: дочерние
OnPush-компоненты всё равно пропускаются, если их не пометили и их входы не изменились; - отличие от
detectChanges(): тот синхронно проверяет компонент и его потомков прямо сейчас, не трогая предков; - где уже вызывается:
AsyncPipeделаетmarkForCheck()на каждое новое значение, а сигналы, прочитанные в шаблоне, помечают свой вид сами.
Типичный случай ручного вызова: OnPush-компонент подписан на поток через subscribe() и меняет поле класса. Без markForCheck() значение появится на экране только при случайной проверке по другой причине.
Где спотыкаются
Говорят, что markForCheck() помечает компонент и его детей. Пометка идёт вверх, к корню, иначе Angular просто не дошёл бы до компонента через OnPush-родителей.
Путают его с detectChanges() и ждут немедленного обновления. Отсюда падающие тесты, где DOM проверяют сразу после вызова, без fixture.detectChanges() или await fixture.whenStable().
Утверждают, что для компонента со стратегией Default вызов бессмыслен. Если такой компонент сидит внутри OnPush-родителя, именно пометка предков позволяет обходу до него дойти.