Как я могу использовать $scope.$ watch и $scope.$применить в AngularJS?
Я не понимаю, как использовать $scope.$watch и $scope.$apply. Официальная документация не помогает.
чего я конкретно не понимаю:
- они подключены к DOM?
- как я могу обновить изменения DOM в модели?
- какова точка соединения между ними?
пробовал в этом уроке, но это требует понимания $watch и $apply для предоставленный.
что делать $apply и $watch есть, и как я могу использовать их соответствующим образом?
7 ответов:
вы должны знать о том, как работает AngularJS, чтобы понять это.
цикл дайджеста и $ scope
прежде всего, AngularJS определяет понятие так называемого дайджест. Этот цикл можно рассматривать как цикл, во время которого AngularJS проверяет, есть ли какие-либо изменения во всех переменных смотрел все
$scopes. Так что если у вас есть$scope.myVarопределено в вашем контроллере и эта переменная была помеченные для за ним наблюдают, то вы неявно говорите AngularJS следить за изменениями наmyVarв каждой итерации цикла.естественным последующим вопросом будет: все ли привязано к
$scopeследят? К счастью, нет. Если бы вы следили за изменениями каждого объекта в вашем$scope, затем быстро цикл дайджеста займет годы, чтобы оценить, и вы быстро столкнетесь с проблемами производительности. Вот почему команда AngularJS дала нам два способа объявить некоторые$scopeпеременная как наблюдаемый (читайте ниже).$watch помогает прослушивать изменения $ scope
есть два способа объявления
$scopeпеременной, как следят.
- используя его в своем шаблоне через выражение
<span>{{myVar}}</span>- добавляя его вручную через
$watchсервисAd 1) Это самый распространенный сценарий, и я уверен, что вы видели его раньше, но вы не знали, что это создало смотрите в фоновом режиме. Да, так оно и было! Использование директив AngularJS (например,
ng-repeat) также может создавать неявные часы.Ad 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 позволяет интеграция изменений с циклом дайджеста
вы можете думать о
, иногда вы хотите измените некоторое значение за пределами мира AngularJS и увидеть изменения, как правило, распространяются. Подумайте об этом-у вас есть$applyфункция как интеграционного механизма. Видите ли, каждый раз, когда вы меняете некоторые наблюдал переменную, прикрепленную к$scopeобъект непосредственно, AngularJS будет знать, что изменение произошло. Это потому, что автор уже знал, чтобы контролировать эти изменения. Поэтому, если это происходит в коде, управляемом платформой, цикл дайджеста будет продолжаться.$scope.myVarзначение, которое будет изменено в пределах jQuery$.ajax()обработчик. Это произойдет в какой-то момент в будущем. AngularJS не может ждать, пока это произойдет, так как он не был проинструктирован ждать jQuery.чтобы справиться с этим,
$applyбыла введена. Это позволяет начать цикл пищеварения явно. Однако, вы должны только используйте это для переноса некоторых данных в AngularJS (интеграция с другими фреймворками), но никогда не используйте этот метод в сочетании с обычным кодом AngularJS, так как AngularJS выдаст ошибку.как все это связано с DOM?
Ну, вы действительно должны следовать учебник снова, теперь, когда вы знаете все это. Цикл дайджеста гарантирует, что пользовательский интерфейс и код JavaScript остаются синхронизированными, оценивая каждый наблюдатель, прикрепленный ко всем
$scopeС тех пор, пока не изменения. Если в цикле дайджеста больше не происходит изменений, то он считается завершенным.вы можете прикрепить объекты к
$scopeобъект либо явно в контроллере, либо объявив их в{{expression}}форма непосредственно в представлении.я надеюсь, что помогает прояснить некоторые базовые знания обо всем этом.
дополнительные материалы:
в AngularJS мы обновляем наши модели, а наши представления/шаблоны обновляют DOM "автоматически" (через встроенные или пользовательские директивы).
$apply и $watch, оба метода Scope, не связаны с DOM.
The концепции страница (раздел "Runtime") имеет довольно хорошее объяснение цикла $digest, $apply, очереди $evalAsync и списка $watch. Вот картинка, которая сопровождает текст:
все код имеет доступ к области-обычно контроллеры и директивы (их функции связи и / или их контроллеры) – можно настроить "watchExpression " что AngularJS будет оценивать против этой области. Эта оценка происходит всякий раз, когда AngularJS входит в свой цикл $digest (в частности, цикл "$watch list"). Вы можете посмотреть его отдельных свойств объема, можно определить функцию, чтобы смотреть вместе два свойства, можно посмотреть длину массива, и т. д.
когда все происходит "внутри AngularJS" -например, вы вводите в текстовое поле, в котором включена двусторонняя привязка данных AngularJS (т. е. использует ng-модель), срабатывает обратный вызов $http и т. д. - $apply уже был вызван, поэтому мы находимся внутри прямоугольника "AngularJS" на рисунке выше. Все выражения watchExpressions будут оцениваться (возможно, более одного раза-до тех пор, пока не будут обнаружены дальнейшие изменения).
когда что-то происходит "вне AngularJS – - например, вы использовали bind() в директиве, а затем это событие срабатывает, в результате чего ваш обратный вызов вызывается, или некоторые зарегистрированные jQuery обратные вызовы-мы все еще находимся в "родном" прямоугольнике. Если код обратного вызова изменяет все, что наблюдает любой $ watch, вызовите $apply, чтобы попасть в прямоугольник AngularJS, заставляя цикл $digest выполняться, и, следовательно, AngularJS заметит изменение и сделает свою магию.
этот блог было охвачено все, что создает примеры и понятные объяснения.
The AngularJS
$scopeфункции$watch(), $digest()и$apply()некоторые из центральных функций в AngularJS. Понимание$watch(),$digest()и$apply()имеет важное значение для того, чтобы понять AngularJS.когда вы создаете привязку данных откуда-то в своем представлении к переменной на объекте $scope, AngularJS создает "часы" внутри. Часы означает, что AngularJS наблюдает за изменениями в переменной на
$scope object. Фреймворк "наблюдает"за переменной. Часы создаются с помощью$scope.$watch()функция, которую я рассмотрю позже в этом тексте.в ключевых точках вашего приложения AngularJS вызывает
AngularJS расширяет это событий-цикл, создавая что-то под названием
AngularJS context.$watch ()
каждый раз, когда вы связываете что-то в пользовательском интерфейсе вы вставляете
$watchна$watchсписок.User: <input type="text" ng-model="user" /> Password: <input type="password" ng-model="pass" />вот и мы
$scope.user, который привязан к первому входу, и у нас есть$scope.pass, который привязан ко второму. При этом мы добавляем два$watches к$watchсписок.когда наши шаблон загружается, он же в фазе связывания, компилятор будет искать каждую директиву и создает все
$watches, которые необходимы.AngularJS обеспечивает
$watch,$watchcollectionи$watch(true). Ниже приведена аккуратная диаграмма, объясняющая все три взятые из наблюдателей глубина.angular.module('MY_APP', []).controller('MyCtrl', MyCtrl) function MyCtrl($scope,$timeout) { $scope.users = [{"name": "vinoth"},{"name":"yusuf"},{"name":"rajini"}]; $scope.$watch("users", function() { console.log("**** reference checkers $watch ****") }); $scope.$watchCollection("users", function() { console.log("**** Collection checkers $watchCollection ****") }); $scope.$watch("users", function() { console.log("**** equality checkers with $watch(true) ****") }, true); $timeout(function(){ console.log("Triggers All ") $scope.users = []; $scope.$digest(); console.log("Triggers $watchCollection and $watch(true)") $scope.users.push({ name: 'Thalaivar'}); $scope.$digest(); console.log("Triggers $watch(true)") $scope.users[0].name = 'Superstar'; $scope.$digest(); }); }
$digestциклкогда браузер получает событие, которое может управляться контекстом AngularJS
$digestцикл будет уволен. Эта петля состоит из двух меньших петель. Один обрабатывает$evalAsyncочередь, а другой обрабатывает$watch list. Элемент$digestбудет цикл по списку$watchчто мы естьapp.controller('MainCtrl', function() { $scope.name = "vinoth"; $scope.changeFoo = function() { $scope.name = "Thalaivar"; } }); {{ name }} <button ng-click="changeFoo()">Change the name</button>здесь у нас только один
$watchпотому что ng-click не создает никаких часов.нажимаем кнопку.
- браузер получает событие, которое войдет в контекст AngularJS
- The
$digestцикл будет работать и будет запрашивать каждые $watch для изменений.- с
$watch, который наблюдал за изменениями в $охвата.название сообщает об изменении, оно заставит другого$digestпетли.- новый цикл ничего не сообщает.
- браузер возвращает элемент управления, и он обновит DOM отражая новое значение $scope.name
- здесь важно то, что каждое событие, которое входит в контекст AngularJS, будет запускать
$digestпетли. Это означает, что каждый раз, когда мы пишем письмо на входе, цикл будет запускать проверку каждого$watchв этой странице.$apply ()
если вы называете
$applyкогда событие срабатывает, он будет идти через угловой контекст, но если вы его не назовете, он будет работать вне его. Это так просто.$applyбудем называть$digest()цикл внутри, и он будет повторяться по всем часам, чтобы гарантировать, что DOM обновляется с недавно обновленным значением.The
$apply()метод вызовет наблюдателей на весь$scopeцепи а$digest()метод будет вызывать только наблюдателей на текущий$scopeиchildren. когда никто из вышестоящих$scopeобъекты должны знать о локальных изменениях, вы можете использовать$digest().
здесь
$watchGroupи$watchCollectionКак хорошо. В частности,$watchGroupдействительно полезно, если вы хотите вызвать функцию для обновления объекта, который имеет несколько свойств в представлении, которое не является объектом dom, например, другое представление в canvas, webGL или запросе сервера. Вот, документация ссылке.
Я нашел очень глубокие видео, которые охватывают
$watch,$apply,$digestи дайджест циклов в:
AngularJS-понимание наблюдателя, $watch, $watchGroup, $watchCollection, ng-change
в AngularJS - понимание дайджест цикла (фаза переварить процесса или усвоить или переварить петли)
Ниже приведены несколько слайдов, используемых в этих видео, чтобы объяснить концепции (на всякий случай, если вышеуказанные ссылки удалены/не работают).
на изображении выше, " $ scope.c " не просматривается, поскольку он не используется ни в одной из Привязок данных (в разметке). Два других (
$scope.aи$scope.b) будет смотрели.из приведенного выше изображения: на основе соответствующего события браузера AngularJS захватывает событие, выполняет цикл дайджеста (проходит через все часы для изменений), выполняет функции часов и обновляет DOM. Если нет событий браузера, цикл дайджеста можно запустить вручную с помощью
$applyили$digest.подробнее о
$applyи$digest:
просто дочитайте все вышесказанное, скучно и сонно (извините, но это правда). Очень технический, глубокий, подробный и сухой. Почему я пишу? Поскольку AngularJS является массивным, множество взаимосвязанных концепций может заставить любого сходить с ума. Я часто спрашивал себя: неужели я недостаточно умен, чтобы понять их? Нет! Это потому, что так мало может объяснить технологию в for-dummie language без всякой терминологии! Хорошо, позвольте мне попробовать:
1) все они управляются событиями вещи. (Я слышу смех, но читайте дальше)
Если вы не знаете, что такое event-driven, то думаю, вы поместите кнопку на странице подключите его с помощью функции "on-click", ожидая пользователи нажимают на него, чтобы вызвать действия, которые вы устанавливаете внутри функция. Или подумайте о "триггере" SQL Server / Oracle.
2) $ watch-это "on-click".
что особенного в том, что он принимает 2 функции как параметры, первый дает значение из события, Второй принимает значение в рассмотрение...
3) $digest-это босс, который неустанно проверяет, бла-бла-бла но хороший босс.
4) $apply дает вам способ, когда вы хотите сделать это вручную, как отказоустойчивый (в случае, если on-click не срабатывает, вы заставляете его работать.)
теперь давайте сделаем его визуально. Представьте это, чтобы сделать его еще более легким возьмите идею:
в ресторане
- официанты должны принимать заказы от клиентов, это
$watch( function(){return orders;}, function(){Kitchen make it;} );- руководителя бег вокруг, чтобы убедиться, что все официанты бодрствуют, реагируя на любые признаки изменений от клиентов. Это
$digest()- собственником имеет максимальную власть, чтобы управлять всеми по запросу, это
$apply()





Comments