Как я могу использовать $scope.$ watch и $scope.$применить в AngularJS?



Я не понимаю, как использовать $scope.$watch и $scope.$apply. Официальная документация не помогает.



чего я конкретно не понимаю:




  • они подключены к DOM?

  • как я могу обновить изменения DOM в модели?

  • какова точка соединения между ними?


пробовал в этом уроке, но это требует понимания $watch и $apply для предоставленный.



что делать $apply и $watch есть, и как я могу использовать их соответствующим образом?

744   7  

7 ответов:

вы должны знать о том, как работает AngularJS, чтобы понять это.

цикл дайджеста и $ scope

прежде всего, AngularJS определяет понятие так называемого дайджест. Этот цикл можно рассматривать как цикл, во время которого AngularJS проверяет, есть ли какие-либо изменения во всех переменных смотрел все $scope s. Так что если у вас есть $scope.myVar определено в вашем контроллере и эта переменная была помеченные для за ним наблюдают, то вы неявно говорите AngularJS следить за изменениями на myVar в каждой итерации цикла.

естественным последующим вопросом будет: все ли привязано к $scope следят? К счастью, нет. Если бы вы следили за изменениями каждого объекта в вашем $scope, затем быстро цикл дайджеста займет годы, чтобы оценить, и вы быстро столкнетесь с проблемами производительности. Вот почему команда AngularJS дала нам два способа объявить некоторые $scope переменная как наблюдаемый (читайте ниже).

$watch помогает прослушивать изменения $ scope

есть два способа объявления $scope переменной, как следят.

  1. используя его в своем шаблоне через выражение <span>{{myVar}}</span>
  2. добавляя его вручную через $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 позволяет интеграция изменений с циклом дайджеста

вы можете думать о $apply функция как интеграционного механизма. Видите ли, каждый раз, когда вы меняете некоторые наблюдал переменную, прикрепленную к $scope объект непосредственно, AngularJS будет знать, что изменение произошло. Это потому, что автор уже знал, чтобы контролировать эти изменения. Поэтому, если это происходит в коде, управляемом платформой, цикл дайджеста будет продолжаться.

, иногда вы хотите измените некоторое значение за пределами мира 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. Вот картинка, которая сопровождает текст:

$digest loop

все код имеет доступ к области-обычно контроллеры и директивы (их функции связи и / или их контроллеры) – можно настроить "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, который привязан ко второму. При этом мы добавляем два $watch es к $watch список.

когда наши шаблон загружается, он же в фазе связывания, компилятор будет искать каждую директиву и создает все $watches, которые необходимы.

AngularJS обеспечивает $watch,$watchcollection и $watch(true). Ниже приведена аккуратная диаграмма, объясняющая все три взятые из наблюдателей глубина.

Enter image description here

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();
  });
}

http://jsfiddle.net/2Lyn0Lkb/

$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 не создает никаких часов.

нажимаем кнопку.

  1. браузер получает событие, которое войдет в контекст AngularJS
  2. The $digest цикл будет работать и будет запрашивать каждые $watch для изменений.
  3. с $watch, который наблюдал за изменениями в $охвата.название сообщает об изменении, оно заставит другого $digest петли.
  4. новый цикл ничего не сообщает.
  5. браузер возвращает элемент управления, и он обновит DOM отражая новое значение $scope.name
  6. здесь важно то, что каждое событие, которое входит в контекст 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 и дайджест циклов в:

Ниже приведены несколько слайдов, используемых в этих видео, чтобы объяснить концепции (на всякий случай, если вышеуказанные ссылки удалены/не работают).

Enter image description here

на изображении выше, " $ scope.c " не просматривается, поскольку он не используется ни в одной из Привязок данных (в разметке). Два других ($scope.a и $scope.b) будет смотрели.

Enter image description here

из приведенного выше изображения: на основе соответствующего события браузера AngularJS захватывает событие, выполняет цикл дайджеста (проходит через все часы для изменений), выполняет функции часов и обновляет DOM. Если нет событий браузера, цикл дайджеста можно запустить вручную с помощью $apply или $digest.

подробнее о $apply и $digest:

Enter image description here

просто дочитайте все вышесказанное, скучно и сонно (извините, но это правда). Очень технический, глубокий, подробный и сухой. Почему я пишу? Поскольку 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

    Ничего не найдено.