Вы должны знать о том, как работает AngularJS, чтобы понять это.
Цикл дайджеста и объем $
Прежде всего, 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}}
форме непосредственно в представлении.
Я надеюсь, что это поможет уточнить некоторые базовые знания обо всем этом.
Дальнейшие чтения:
В AngularJS мы обновляем наши модели, а наши представления / шаблоны обновляют DOM «автоматически» (с помощью встроенных или пользовательских директив).
$ apply и $ watch, оба являются методами Scope, не связаны с DOM.
Страница Concepts (раздел «Runtime») содержит довольно хорошее объяснение цикла $ digest, $ apply, очереди $ evalAsync и списка $ watch. Вот картинка, которая сопровождает текст:
Какой бы код не имел доступ к области действия - обычно контроллеры и директивы (их функции связи и / или их контроллеры) - могут установить « watchExpression », которое AngularJS будет оценивать по отношению к этой области. Эта оценка происходит всякий раз, когда AngularJS входит в свой цикл $ digest (в частности, цикл «$ watch list»). Вы можете наблюдать отдельные свойства области, вы можете определить функцию для просмотра двух свойств вместе, вы можете наблюдать длину массива и т. Д.
Когда что-то происходит «внутри AngularJS» - например, вы вводите текстовое поле с включенной двусторонней привязкой данных AngularJS (т. Е. Использует ng-модель), срабатывает обратный вызов $ http и т. Д. - $ apply уже был вызван, поэтому мы Вы находитесь внутри прямоугольника "AngularJS" на рисунке выше. Все watchExpressions будут оцениваться (возможно, более одного раза - до тех пор, пока дальнейшие изменения не будут обнаружены).
Когда что-то происходит «вне AngularJS» - например, вы использовали bind () в директиве, а затем это событие запускается, в результате чего вызывается ваш обратный вызов, или регистрируются некоторые вызовы обратного вызова, зарегистрированные в jQuery, - мы все еще находимся в прямоугольнике «Native». Если код обратного вызова изменяет что-либо, что наблюдает любой $ watch, вызовите $ apply, чтобы попасть в прямоугольник AngularJS, в результате чего запустится цикл $ digest, и, следовательно, AngularJS заметит это изменение и сделает его магию.
источник
scope.$apply(scope.model)
, я не понимаю, какие данные передаются и как они передаются в нужное место в модели?scope.$apply(scope.model)
просто оценитscope.model
как угловое выражение, а затем введет цикл $ digest. В статье, на которую вы ссылаетесь, вероятноscope.$apply()
, будет достаточно, поскольку модель уже отслеживается. Функция stop () обновляет модель (я считаю, что toUpdate - это ссылка на scope.model), а затем вызывается $ apply.$watch
на странице, а вторая ссылка не работает - на данный момент, во всяком случае). К сожалению, версии архива не кэшировали какой-либо асинхронный процесс, создававший контент.AngularJS расширяет этот цикл обработки событий , создавая нечто, называемое
AngularJS context
.$ Часы ()
Каждый раз, когда вы связываете что-то в пользовательском интерфейсе, вы вставляете
$watch
в$watch
список .Здесь мы имеем
$scope.user
, что связано с первым входом, и мы имеем$scope.pass
, который связан со вторым. Делая это, мы добавляем два списка$watch
в$watch
список .Когда наш шаблон загружен, AKA на этапе компоновки, компилятор будет искать каждую директиву и создавать все
$watch
необходимые ей.AngularJS обеспечивает
$watch
,$watchcollection
и$watch(true)
. Ниже приведена аккуратная диаграмма, подробно объясняющая все три, взятые у наблюдателей .http://jsfiddle.net/2Lyn0Lkb/
$digest
петляКогда браузер получает событие, которое может управляться контекстом AngularJS,
$digest
цикл запускается. Эта петля сделана из двух меньших петель. Один обрабатывает$evalAsync
очередь, а другой обрабатывает$watch list
.$digest
Будет цикл по списку ,$watch
что мы имеемЗдесь у нас есть только один,
$watch
потому что ng-click не создает никаких часов.Нажимаем кнопку.
$digest
Цикл будет работать и будет просить каждый $ наблюдать за изменениями.$watch
который следил за изменениями в $ scope.name, сообщает об изменении, он вызовет другой$digest
цикл.$digest
цикл. Это означает, что каждый раз, когда мы пишем букву на входе, цикл запускает проверку каждого$watch
на этой странице.$ Применяются ()
Если вы вызываете,
$apply
когда происходит событие, оно пройдет через угловой контекст, но если вы его не вызовите, оно выйдет за его пределы. Это так просто.$apply
вызовет$digest()
цикл внутри, и он будет перебирать все часы, чтобы убедиться, что DOM обновляется с новым обновленным значением.$apply()
Метод будет вызывать наблюдатель по всей$scope
цепи , тогда как$digest()
метод будет только вызвать наблюдатель на текущем$scope
и ееchildren
. Когда ни один из вышестоящих$scope
объектов не должен знать о локальных изменениях, вы можете использовать$digest()
.источник
Я нашел очень углубленное видео , которые охватывают
$watch
,$apply
,$digest
и переварить циклы:AngularJS - Понимание Watcher, $ watch, $ watchGroup, $ watchCollection, ng-change
AngularJS - Понимание цикла дайджеста (фаза дайджеста, процесс дайджеста или цикл дайджеста)
AngularJS Tutorial - Понимание $ apply и $ digest (подробно)
Ниже приведено несколько слайдов, используемых в этих видеороликах для объяснения концепции (на всякий случай, если вышеуказанные ссылки удалены / не работают).
На изображении выше «$ scope.c» не отслеживается, поскольку не используется ни в одной из привязок данных (в разметке). Два других (
$scope.a
и$scope.b
) будут смотреться.На изображении выше: на основе соответствующего события браузера AngularJS захватывает событие, выполняет цикл дайджеста (проходит все отслеживания изменений), выполняет функции отслеживания и обновляет DOM. Если не события браузера, цикл дайджеста можно запустить вручную с помощью
$apply
или$digest
.Подробнее о
$apply
и$digest
:источник
Есть
$watchGroup
и$watchCollection
так же. В частности,$watchGroup
действительно полезно, если вы хотите вызвать функцию для обновления объекта, который имеет несколько свойств в представлении, которое не является объектом dom, например, для другого представления в canvas, WebGL или запросе к серверу.Здесь ссылка на документацию .
источник
$watchCollection
но я вижу, вы уже сделали. Вот документация об этом с сайта AngularJS. Они обеспечивают очень хорошее визуальное представление о$watch
глубине. Обратите внимание, что информация находится близко к нижней части страницы.Просто закончите читать ВСЕ выше, скучно и сонно (извините, но это правда). Очень технический, глубокий, подробный и сухой. Почему я пишу? Поскольку AngularJS огромен, множество взаимосвязанных концепций может свести с ума любого. Я часто спрашивал себя, я не достаточно умен, чтобы понять их? Нет! Это потому, что очень немногие могут объяснить технологию на пустышке без всякой терминологии! Хорошо, позвольте мне попробовать:
1) Все это вещи, управляемые событиями. (Я слышу смех, но продолжаю читать)
Если вы не знаете, что такое событие, управляемое событиями, то подумайте, что вы помещаете кнопку на страницу, подключаете ее с помощью функции «по нажатию», ожидая, пока пользователи нажмут на нее, чтобы вызвать действия, которые вы внедрите внутри функция. Или подумайте о «триггере» SQL Server / Oracle.
2) $ watch "на клике".
Что особенного в том, что он принимает 2 функции в качестве параметров, первая дает значение из события, вторая принимает значение во внимание ...
3) $ digest - босс, который неустанно проверяет , бла-бла-бла, но хороший босс.
4) $ apply дает вам способ, когда вы хотите сделать это вручную , например, как отказоустойчивый (в случае, если щелчок не срабатывает, вы заставляете его работать).
В ресторане,
- Официанты
должны принимать заказы от клиентов, это
- УПРАВЛЯЮЩИЙ ДЕЛАМИ бегает, чтобы убедиться, что все официанты проснулись, реагируя на любые признаки изменений со стороны клиентов. Это
$digest()
- ВЛАДЕЛЕЦ имеет максимальную силу, чтобы водить всех по запросу, это
$apply()
источник