вторник, 12 августа 2014 г.

AngularJS: $watch, $digest and $apply

Что такое $watch?

Давайте поговорим об этом первым. $watch - это, пожалуй, наиболее важные внутренние функции Angular. $watch могут использоваться, чтобы смотреть любое значение, и инициация вызова функции, когда это значение изменяется. $watch могут быть созданы из любого $scope, позвонив в $scope.$watch (), как показано ниже.

Настройка $watch

Существует два способа настроить $watch, выражения или функции. Технически, они оба делают то же самое. Если передать выражение (строку), он будет оцениваться от $scope и преобразуется в функцию, чтобы быть под наблюдением. Если вы передаете функцию, это просто $watch, функция, преобразование не требуется.

По Выражению

Следующий будет смотреть 'foo'. Который представляет собой выражение, против $scope.

//$scope.$watch(<function/expression>, <handler>);
 $scope.$watch('foo', function(newVal, oldVal) {
    console.log(newVal, oldVal);
});


По Функции

На создание $watch по функциям, вы можете сделать следующее, технически же, как показано выше:

$scope.$watch(function() {
    return $scope.foo;
}, function(newVal, oldVal) {
    console.log(newVal, oldVal);
});

Факты о $watch:

Наблюдатель может оценить любое значение.
Наблюдатель обработчик сможет выполнить ничего когда вышеупомянутое значение изменилось.
Все наблюдатели вычисляются при $digest() называется.
Если первый аргумент $watch строка, то $eval в функцию, до регистрации. Это функционально эквивалентно передаче функции в качестве первого аргумента, только с дополнительным этапом внутренне.

Что такое $digest?

В это суть, главное, что нужно знать о $digest заключается в том, что он перебирает все watchers по области видимости он был вызван и его дочерние области. и оценивает их, чтобы увидеть, если они изменились, исполняющими их обработчики, если они есть. Это важная часть, которую нужно знать.

Как позвонить в $digest:

$область.$digest();



Что такое $apply?

Проще говоря, это оболочка $rootScope.$digest, который оценивает любое выражение, переданное ему до вызова $digest(). Вот именно. Так что, если вы называете это " сам по себе, без передачи аргумента, а может быть, вы просто позвоните $digest().

Как вызвать  $apply:

$scope.$apply('foo = "test"');
//or
$scope.$apply(function(scope) {
    scope.foo = 'test';
});
//or
$scope.$apply(function(){
    $scope.foo = 'test';
});

Так когда же $digest/$apply случиться?

В ключевые моменты определенных рамках. Angular построен в вызовах $digest и $apply к ее услугах и директивы, а также некоторые внутренние вызовы. Но в основном это, как это, такие вещи, как $timeout выполнения setTimeout, то колл на $apply или $digest (фактическое делает нечто большее, чем то, но вот основная идея). $http.get(), одни и те же сделки, делает AJAX-вызов, возвращает его, то очереди до $digest. То есть директивы, как входы с ngModel например. Обновления на вход, будут также вызывать $digest. Вы получаете идею.

Как сделать $watch, $digest и $apply связи с обновлением моего представления?


Директива регистрирует $watch, которая ищет изменения в модели по $scope. Обработчик будет обновить DOM-значение элемента.
Директива регистрирует обработчик событий определенного рода, в DOM, который будет получать значение из DOM и применить его к модели в $scope. Он также будет вызывать $ " применить " или " $digest.
При обновлении модели в область через некоторые рамки звонка... $http.get() например, он стартует $digest после ее завершения.
$digest  проверяет $watch директива регистрацию, видит изменения и запускает обработчик, связанный, обновление DOM-элемент.

Почему Angular работает таким образом?

Также вы можете наблюдать setter и getter на известные свойства в реальном времени, но там действительно нет возможности строить событие в добавлении новых значений или удаление значений из объекта или массива, особенно когда это делается с помощью индексатора, ала хэш-таблица или индекс массива. Итак, дайджест становится необходимым. Откуда я это знаю? Потому что я пытался писать собственный фреймворк и быстро нашел себя писать half-assed версии Angular. Единственный вариант, который я знаю, было бы полностью завернуть модели наблюдения в конструкцию при помощи функции set() и get() функции... думаю, нокаут... что делает JavaScript код уродливее работать с (IMO).

Некоторые Рекомендации По Применению:

$watch
  • Делать используйте $watch в директивы для обновления DOM, когда $scope изменения стоимости.
  • НЕ используйте $watch в контроллере. Это трудно испытания и совершенно ненужным, почти в каждом случае. Использование метода на область, чтобы обновить значение $watch меняется вместо.
$digest/$apply
  • Делать используйте $digest/$apply в директивы пусть Angular знает, что вы внесли изменения после асинхронного вызова, такие как DOM-события.
  • Делать используйте $digest/$apply в услуги пусть Angular знает некоторые асинхронной операции вернулся, такие как WebSocket обновления, или события из 3-й партии библиотеки, например, Facebook API.
  • НЕ используйте $digest/$обращаться в контроллер. Это сделает ваш код сложнее тестировать, так и асинхронные операции за пределами Angular, не входят в ваши контроллеры. Они входят в услуги и директив.

Когда использовать $apply или $digest?


[EDIT: для пояснения о том, когда их следует использовать] $scope.$digest должны будут редко использоваться и вне каких-то очень конкретных экземпляров. Такие, как изолированные области в директиве, которые, возможно, захотите обновить только себя. Или, в крайнем случае если в области действия объекта, был создан для некоторых других изолированных цели. $scope.$apply или $rootScope.$digest должен быть выбран большую часть времени, так как общий желаемый эффект, чтобы обновить весь вид или модель.

Перевод: http://www.benlesh.com/2013/08/angularjs-watch-digest-and-apply-oh-my.html

Комментариев нет:

Отправить комментарий