Как проверить, стабилизировались ли циклы дайджеста ("Закончила ли угловая компиляция?")

tl;dr: Первоначальный вопрос был "Как вызвать обратный вызов при каждом цикле дайджеста?" но основной вопрос гораздо интереснее, и так как он отвечает на оба вопроса, я пошел дальше и изменил название. знак равно

Контекст: я пытаюсь контролировать, когда angular завершил компиляцию HTML (по причинам, связанным с предварительным рендерингом SEO), после разрешения всех его зависимостей, nginclude, вызовов API и т. Д. "Самый умный" способ, который я нашел до сих пор, - это проверка, Циклы переваривания стабилизировались.
Поэтому я решил, что если я буду запускать обратный вызов каждый раз, когда запускается цикл дайджеста, и удерживать текущее время, если в течение произвольного промежутка (2000 мс) не будет запущен другой цикл, мы можем считать, что компиляция стабилизировалась, и страница готов к архивированию для поисковых роботов SEO.

Прогресс на данный момент: я полагал, что просмотр фазы $rootScope.$$ мог бы быть успешным, но, хотя многие взаимодействия должны запускать этот наблюдатель, я обнаружил, что он срабатывает только один раз, при самой первой загрузке.

Вот мой код:

app.run(function ($rootScope) {
  var lastTimeout;
  var off = $rootScope.$watch('$$phase', function (newPhase) {
    if (newPhase) {
      if (lastTimeout) {
        clearTimeout(lastTimeout);
      }
      lastTimeout = setTimeout(function () {
        alert('Page stabilized!');
      }, 2000);
    }
  });



Решение: Добавлено решение Mr_Mig (слава) и некоторые улучшения.

app.run(function ($rootScope) {
  var lastTimeout;
  var off = $rootScope.$watch(function () {
    if (lastTimeout) {
      clearTimeout(lastTimeout);
    }
    lastTimeout = setTimeout(function() {
      off(); // comment if you want to track every digest stabilization
      // custom logic
    }, 2000);
  });
});

1 ответ

Решение

Я на самом деле не знаю, ответит ли мой совет на ваш вопрос, но вы могли бы просто передать слушателя $watch функция, которая будет вызываться на каждой итерации:

$rootScope.$watch(function(oldVal, newVal){
    // add some logic here which will be called on each digest cycle
});

Посмотрите здесь: http://docs.angularjs.org/api/ng/type/%24rootScope.Scope

Другие вопросы по тегам