Angular. Зачем вызывать результаты markForCheck () для просмотра обновления - PullRequest
2 голосов
/ 25 мая 2020

Везде говорится, что markForCheck просто помечает текущее представление компонента и все родительские компоненты (вплоть до root) как грязные. Поэтому в следующий раз, когда выполнится DetectChanges, он обновит представление. С этого момента у меня есть 2 вопроса. Оба в контексте этого компонента имеют changeDetection: ChangeDetectionStrategy.OnPush

1) Если 'asyn c pipe' ничего не делает, кроме вызова markForCheck ( исходный код ), почему представление обновляется?

2) Если я попытаюсь вызвать markForCheck внутри некоторого процесса asyn c, представление также будет обновлено.

Демонстрация: stackblitz

Можете ли вы помочь мне понять, что происходит во время этих процессов и почему представление действительно обновляется? Я ожидаю, что кто-то вызовет метод DetectChanges после 1) и 2), но кто ...

Ответы [ 2 ]

2 голосов
/ 27 мая 2020

С помощью @David я нашел ответ.

Перво-наперво, Rx Js в любом случае не обернут зоной, но встроенные функции asyn c (как setTimer/Iterval, fetch api, XHR, DOM events). Поскольку операторы Rx Js timer / delay (...) используют собственные функции asyn c, это приводит к тому, что они также обрабатываются в контексте зоны.

Вот как выглядит стек вызовов, когда мы находимся в операторе Rx tap

enter image description here Вы можете видеть, что часть Rx идет после Angular / Zone .

Angular в свою очередь использует зону для вызова функции tick() всякий раз, когда выполняется обратный вызов asyn c. Метод Tick идет вниз от компонента root и ищет отмеченные для проверки представления.

Я помещаю точку останова в функцию тика, он вызывается после выполнения нашего обратного вызова

enter image description here

Итак, что происходит в первом случае, когда мы используем async pipe в шаблоне.

  1. Asyn c обратный вызов обрабатывается оператором asyn c pipe, а функция markForCheck () вызывается
  2. Как мы знаем, markForCheck отмечает текущие и родительские представления вплоть до RootComponent для проверка
  3. После выполнения обратного вызова с шага 1 вызывается tick(). Что, наконец, проверит представление и обновит его

И почти то же самое происходит во втором случае, когда мы вызываем markForCheck внутри оператора Rx Js. Мы делаем то же самое, что и async pipe, и поскольку наш обратный вызов также заключен в зону, у нас есть тот же процесс, который будет выполняться после выполнения обратного вызова.

Если вы не вызовете markForCheck в своем asyn c обратный вызов, но вызов функции тика, обновление не будет. Стоит упомянуть, что если вы вызовете detectChanges (), обновление будет выполнено, несмотря на то, что функция markForCheck не была вызвана. Вот пример на stackblitz Это связано с тем, что DetechChanges из ChangeDetectorRef игнорирует флаг markForCheck и обнаруживает изменения для Component и всех его дочерних элементов. Более подробная информация содержится в этой статье

Этот метод запускает обнаружение изменений для текущего представления компонента независимо от его состояния

0 голосов
/ 25 мая 2020

См. Во время onpu sh, любые изменения во входных данных делают компонент грязным, и тогда выполняется только повторный рендеринг. Но если вы хотите сделать его грязным даже без этих событий, вы можете вызвать метод markDirty для выполнения changeDetection. Пожалуйста, найдите ссылку на официальное заявление ниже: -

официальное заявление

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