Вам нужно знать, как работает AngularJS, чтобы понять это.
Цикл дайджеста и $ scope
Прежде всего, AngularJS определяет концепцию так называемого цикла дайджеста. Этот цикл можно рассматривать как цикл, во время которого AngularJS проверяет, есть ли какие-либо изменения для всех переменных, наблюдаемых всеми $scope
s. Итак, если у вас есть $scope.myVar
, определенный в вашем контроллере, и эта переменная была помечена для наблюдения, то вы неявно указываете AngularJS отслеживать изменения в myVar
на каждой итерации цикла.
Естественным последующим вопросом будет: Наблюдается ли все, что связано с $scope
? К счастью, нет. Если вы будете следить за изменениями каждого объекта в вашем $scope
, то быстро цикл дайджеста займет много времени, чтобы оценить, и вы быстро столкнетесь с проблемами производительности. Вот почему команда AngularJS дала нам два способа объявления некоторой $scope
переменной как наблюдаемой (читайте ниже).
$ watch помогает отслеживать изменения $ scope
Есть два способа объявить переменную $scope
как наблюдаемую.
- Используя его в своем шаблоне через выражение
<span>{{myVar}}</span>
- Добавляя его вручную через службу
$watch
Объявление 1) Это наиболее распространенный сценарий, и я уверен, что вы видели его раньше, но не знали, что это создает часы в фоновом режиме. Да, было! Использование директив AngularJS (например, ng-repeat
) также может создавать неявные часы.
Объявление 2) Таким образом вы создаете свои собственные часы. Служба $watch
помогает запустить код, когда какое-то значение, прикрепленное к $scope
, изменилось. Используется редко, но иногда бывает полезным. Например, если вы хотите запускать какой-то код каждый раз при изменении myVar, вы можете сделать следующее:
function MyController($scope) {
$scope.myVar = 1;
$scope.$watch('myVar', function() {
alert('hey, myVar has changed!');
});
$scope.buttonClicked = function() {
$scope.myVar = 2; // This will trigger $watch expression to kick in
};
}
$ apply позволяет интегрировать изменения в цикл дайджеста
Вы можете думать о $apply
функции как о механизме интеграции. Видите ли, каждый раз, когда вы изменяете некоторую наблюдаемую переменную, прикрепленную к объекту $scope
напрямую, AngularJS будет знать, что изменение произошло. Это потому, что AngularJS уже знал, как отслеживать эти изменения. Так что, если это происходит в коде, управляемом фреймворком, цикл дайджеста будет продолжен.
Однако иногда вы хотите изменить какое-либо значение за пределами мира AngularJS и увидеть, как изменения распространяются нормально. Учтите это - у вас есть значение $scope.myVar
, которое будет изменено в обработчике $.ajax()
jQuery. Это произойдет когда-нибудь в будущем. AngularJS не может дождаться, когда это произойдет, поскольку ему не было предписано ждать на jQuery.
Для решения этой проблемы был введен $apply
. Это позволяет вам явно запустить цикл пищеварения. Однако вы должны использовать это только для переноса некоторых данных в AngularJS (интеграция с другими фреймворками), но никогда не используйте этот метод в сочетании с обычным кодом AngularJS, поскольку тогда AngularJS выдаст ошибку.
Как все это связано с DOM?
Что ж, вам действительно стоит снова следовать руководству, теперь, когда вы все это знаете. Цикл дайджеста гарантирует, что пользовательский интерфейс и код JavaScript остаются синхронизированными, путем оценки каждого наблюдателя, прикрепленного ко всем $scope
s, пока ничего не изменится. Если в цикле дайджеста больше не происходит изменений, он считается завершенным.
Вы можете присоединять объекты к объекту $scope
либо явно в Контроллере, либо путем объявления их в форме {{expression}}
непосредственно в представлении.
Я надеюсь, что это поможет прояснить некоторые базовые знания обо всем этом.
Дальнейшие чтения:
person
ŁukaszBachman
schedule
27.02.2013