Когда вызывается цикл $digest?
Я очень смущен, когда происходит цикл дайджеста, он называется периодически на основе таймера каждые 50 мс (как он говорит здесь и подразумевается здесь) или вызывается после каждого события, которое входит в контекст angular (как сказано здесь, здесь и здесь)?
Пример, когда это важно:
В моей модели у меня есть переменная с именем myVar
со значением 3.
В моем HTML у меня есть {{myvar}}
.
Событие, такое как нажатие кнопки, запускается и вызывает обработчик в контроллере, код внутри обработчика:
$scope.myVar = 4;
// some heavy actions takes place for 3 seconds...
$scope.myVar = 5;
Предполагая, что поток пользовательского интерфейса не заблокирован, что увидит пользователь после нажатия кнопки? он увидит только 5 или он увидит 4 и через 3 секунды 5?
Ответы
Ответ 1
Я думаю, что описание цикла дайджеста на http://blog.bguiz.com/post/60397801810/digest-cycles-in-single-page-apps, что это
который выполняется с интервалом
очень вводит в заблуждение, и, если честно, когда ссылаюсь на Angular, я бы даже сказал неправильно. Процитировать Pawel Kozlowski, Освоение разработки веб-приложений с помощью AngularJS
AngularJS не использует какой-либо механизм опроса для периодической проверки изменений модели
Чтобы доказать отсутствие опроса, если у вас есть шаблон
<p>{{state}}</p>
и код контроллера
$scope.state = 'Initial';
// Deliberately *not* using $timeout here
$window.setTimeout(function() {
$scope.state = 'Changed';
},1000);
как в этом plunker, строка, показанная пользователю, останется как Initial
и никогда не изменится на Changed
.
Если вам интересно, почему вы часто видите вызовы $apply
, но не всегда, вероятно, потому, что различные директивы, которые поставляются с Angular, например ngClick
или ngChange
, вызывают $apply
сами, что затем вызовет цикл. Слушатели событий для собственных событий JS напрямую не будут делать этого, поэтому им придется сознательно вызывать $apply
, чтобы любые изменения отражались в шаблонах.
Ответ 2
Процесс дайджестов запускается, когда в контексте angular происходит какое-либо из следующих действий:
- События DOM (например, ng-click и т.д.).
- Ajax с обратными вызовами ($ http и т.д.)
- Таймеры с обратными вызовами ($ timeout и т.д.)
- вызов $apply, $digest
- и др.
Важно отметить, что обычные события DOM, связанные с браузером (onclick и т.д.) и setTimeout не будут вызывать процесс дайджеста, поскольку они работают из "Angular Контекст".
Я понял следующее из следующего:
![Angularjs Digest Cycle - TechCBT]()
Вышеприведенный быстрый снимок из очень углубленного учебника, доступного здесь: https://www.youtube.com/watch?v=SYuc1oSjhgY
Ответ 3
Любая переменная области AngularJS при обработке извне (включая ajax) нуждается в $apply().
setTimeout
- это функция Javascript. Для обновления значений угловых значений требуется $apply
.
$timeout
- функция угловой функции, которая возвращает обещание и заботится о текущей области действия и работает в том же цикле дайджест.
Поэтому для обновления значений не требуется функция $apply()
.