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