Как использовать $scope.$ watch и $scope.$применить в AngularJS?
Я не понимаю, как использовать $scope.$watch
и $scope.$apply
. Официальная документация не помогает.
чего я не понимаю конкретно:
- они связаны с DOM?
- как я могу обновить изменения DOM в модели?
- какова точка связи между ними?
пробовал в этом уроке, но это требует понимания $watch
и $apply
для предоставленный.
что делать $apply
и $watch
do, и как я могу использовать их соответствующим образом?
7 ответов
вы должны знать о том, как 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 позволяет интеграция изменений с циклом digest
вы можете думать о $apply
функция как механизма интеграции. Видите ли, каждый раз, когда вы меняете некоторые наблюдал переменную, прикрепленную к $scope
объект напрямую, AngularJS будет знать, что изменение произошло. Это потому, что AngularJS уже знал, чтобы отслеживать эти изменения. Поэтому, если это происходит в коде, управляемом платформой, цикл дайджеста будет продолжаться.
$scope.myVar
значение, которое будет изменено в jQuery $.ajax()
обработчик. Это произойдет в какой-то момент в будущем. AngularJS не может дождаться этого, так как ему не было поручено ждать jQuery.
чтобы справиться с этим,$apply
была введена. Это позволяет начать цикл пищеварения явно. Однако, вы должны только используйте это для переноса некоторых данных в AngularJS (интеграция с другими фреймворками), но никогда не используйте этот метод в сочетании с обычным кодом AngularJS, так как AngularJS выдаст ошибку.
как все это связано с DOM?
Ну, вы должны действительно следовать учебник снова, теперь, когда вы знаете все это. Цикл дайджеста обеспечит синхронизацию пользовательского интерфейса и кода JavaScript, оценив каждый наблюдатель, прикрепленный ко всем $scope
s до тех пор, пока ничего изменения. Если в цикле дайджеста больше не происходит изменений, то он считается законченным.
вы можете прикрепить объекты к $scope
объект либо явно в контроллере, либо путем объявления их в {{expression}}
форма непосредственно в представлении.
я надеюсь, что помогает прояснить некоторые базовые знания обо всем этом.
дополнительные материалы:
в AngularJS мы обновляем наши модели, а наши представления/шаблоны обновляют DOM "автоматически" (через встроенные или пользовательские директивы).
$apply и $watch, оба метода области, не связаны с DOM.
на концепции страница (раздел "время выполнения") имеет довольно хорошее объяснение цикла $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 заметит изменение и сделает свою магию.
этот блог было охвачено все, что создает примеры и понятные объяснения.
В В AngularJS $scope
функции $watch(), $digest()
и $apply()
некоторые из центральных функций в AngularJS. Понимание $watch()
, $digest()
и $apply()
имеет важное значение для того, чтобы понять AngularJS.
когда вы создаете привязку данных откуда-то в своем представлении к переменной на объекте $scope, AngularJS создает "часы" внутри. Часы означает, что AngularJS наблюдает за изменениями переменной на $scope object
. Фреймворк "наблюдает" за переменной. Часы создаются с помощью $scope.$watch()
функция, которую я рассмотрю позже в этом тексте.
в ключевых точках вашего приложения AngularJS вызывает
AngularJS расширяет это события-loop, создание чего-то под названием AngularJS context
.
$watch ()
каждый раз, когда вы связываете что-то в пользовательском интерфейсе, вы вставляете $watch
на $watch
список.
User: <input type="text" ng-model="user" />
Password: <input type="password" ng-model="pass" />
здесь мы имеем $scope.user
, который привязан к первому входу, и у нас есть $scope.pass
, который привязан ко второму. Делая это, мы добавляем два $watch
es к $watch
список.
когда наши шаблон загружается, АКА в фазе связывания, компилятор будет искать каждую директиву и создает все $watch
es, которые необходимы.
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
. The $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
- на
$digest
цикл будет работать и будет запрашивать каждые $watch для изменений. - с
$watch
, который наблюдал за изменениями в $охвата.название сообщает об изменении, это заставит другого$digest
петли. - новый петля ничего не сообщает.
- браузер возвращает элемент управления, и он обновит DOM отражение нового значения $ scope.имя
- важно то, что каждое событие, которое входит в контекст AngularJS, будет запускать
$digest
петли. Это означает, что каждый раз, когда мы пишем письмо на входе, цикл будет запускать проверку каждого$watch
в этой странице.
$apply ()
если вы называете $apply
когда событие уволено, оно пойдет через угловой контекст, но если вы его не назовете, он будет работать вне его. Это так просто. $apply
будем называть $digest()
цикл внутри, и он будет повторяться по всем часам, чтобы гарантировать, что DOM обновляется с недавно обновленным значением.
на $apply()
метод вызовет наблюдателей на весь $scope
цепи а $digest()
метод будет вызывать только наблюдателей на текущем $scope
и children
. когда ни один из выше $scope
объекты должны знать о локальных изменениях, вы можете использовать $digest()
.
здесь $watchGroup
и $watchCollection
Как хорошо. В частности, $watchGroup
действительно полезно, если вы хотите вызвать функцию для обновления объекта, который имеет несколько свойств в представлении, которое не является объектом dom, например, другое представление в canvas, webGL или Server request. Вот, документация ссылке.
Я нашел очень глубокие видео, которые охватывают $watch
, $apply
, $digest
и дайджест циклов в:
AngularJS-понимание наблюдателя, $ watch, $watchGroup, $watchCollection, ng-change
AngularJS-понимание цикла дайджеста (этап дайджеста или процесс дайджеста или цикл дайджеста)
Ниже приведены несколько слайдов, используемых в этих видео, чтобы объяснить концепции (на всякий случай, если вышеуказанные ссылки удалены/не работают).
на приведенном выше изображении " $ scope.c " не отслеживается, поскольку он не используется ни в одной из Привязок данных (в разметке). Двое других ($scope.a
и $scope.b
) будет смотрели.
из приведенного выше изображения: на основе соответствующего события браузера AngularJS захватывает событие, выполняет цикл дайджеста (проходит через все часы для изменений), выполняет функции часов и обновляет DOM. Если не события браузера, цикл дайджеста можно запустить вручную с помощью $apply
или $digest
.
подробнее о $apply
и $digest
:
просто закончите читать все выше, скучно и сонно (извините, но это правда). Очень технический, глубокий, подробный и сухой. Зачем я пишу? Поскольку AngularJS массивен, множество взаимосвязанных концепций может свести с ума любого. Я часто спрашивал себя: неужели я недостаточно умен, чтобы понять их? Нет! Это потому, что так мало может объяснить технологию в для dummie язык без всех терминологий! Ладно, попробую:
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()