Что считается наблюдателем в Angular?

Что считается " наблюдатели" в Angular? Являются ли наблюдатели самими наблюдателями, или являются другими конструкциями Angular, такими как ngModel наблюдатели?

Или мне не хватает большой картины? Например, являются ли наблюдатели доступными для таких директив, как ngModel?

update: есть ли способ сказать, когда существуют наблюдатели? При тестировании я хочу знать, когда нужно называть область. $Digest()

+5
источник поделиться
3 ответа

watchers - не что иное, как грязная проверка, которая отслеживает старое значение и новое значение

Они оцениваются в каждом цикле дайджеста. Это может быть комбинация переменной области видимости или любого выражения. Angular собирает всех этих наблюдателей в каждом цикле дайджест и mainatain внутри массива $$watchers. вы можете посмотреть, сколько наблюдателей там, выполнив console.log($scope.$watchers) внутри вашего контроллера.

Разметка

<body class="container" ng-controller="myCtrl">
  Hello {{test}}
  I'm test to show $$watchers {{test1}}
  <div ng-show="show">SHowiing this div using ng-show</div>
  <div ng-if="show">SHowiing this div using ng-show</div>
  Watcher is not compulsary that should scope variables {{'1'}}
</body>

Plunkr

Угадайте в приведенном выше коде, сколько наблюдателей есть, так как вы можете видеть, что есть 3 {{}} директива интерполяции, которые собираются разместить в массиве наблюдателей, а затем, если вы видите на консоли $scope.$$watchers, она покажет 5 наблюдателей.

Как получилось, это показывает 5 наблюдателей. Как мы видим только 3, на самом деле мы использовали директиву ng-show и ng-if, которые внутренне помещают $watch в выражение, указанное в его значении атрибута. и это выражение оценивается в каждом цикле дайджест.

Вы также можете создать свой пользовательский наблюдатель, используя $watch (глубокие/простые часы) и $watchGroup

Также вы могли бы использовать наблюдателя $attrs.$observe, это работает так же, как и часы, но единственное, что он делает, он работает для переменной интерполяции.

$attrs.$observe('test',function(value){
    alert('')
});

Большинство директив Angular внутренне использует наблюдателя как ng-repeat, ng-show, ng-if, ng-include, ng-switch, ng-bind, директиву интерполяции {{}}, фильтры и т.д. Они ставят часы внутренне управлять двухсторонней привязкой.

+2
источник

Наблюдатели (если взять только документацию, на которой вы основаны) являются механизмами angular, которые стремятся наблюдать в стиле двусторонней привязки переменную или результат функции во время любого цикла angular digest; и независимо от того, каким будет инициирующее событие цикла дайджеста.

Я бы назвал "наблюдателем" любой механизм angular, который может запускать некоторые коды на основе ЛЮБОГО события, которое может произойти.

Как правило, для создания наблюдателя вы должны использовать: $scope.watch(...)

Просто имейте в виду, что лучше избегать наблюдателей, сколько мы можем.
Действительно, их обратный вызов будет запускаться в КАЖДОМ цикле дайджеста, чтобы выполнить грязную проверку; часто влияя на производительность.

ng-model не связан с концепцией наблюдателя.
 ng-model - это просто способ привязки некоторой переменной от представления к контроллеру.
Это две разные концепции.

+1
источник

Чтобы проиллюстрировать, как работают функции $watch(), $digest() и $apply(), посмотрите на этот пример:

<div ng-controller="myController">
{{data.time}}

<br/>
<button ng-click="updateTime()">update time - ng-click</button>
<button id="updateTimeButton"  >update time</button>
</div>
<script>
var module = angular.module("myapp", []);
var myController1 = module.controller("myController", function($scope) {
    $scope.data = { time : new Date() };
    $scope.updateTime = function() {
        $scope.data.time = new Date();
    }
    document.getElementById("updateTimeButton")
            .addEventListener('click', function() {
        console.log("update time clicked");
        $scope.data.time = new Date();
    });
});
</script>

В этом примере привязка переменной $scope.data.time к директиве интерполяции, которая объединяет значение переменной в HTML-страницу. Это связывание создает часы внутри переменной $scope.data.time.

Пример также содержит две кнопки. Первая кнопка имеет прикрепленный к ней прослушиватель ng-click. Когда эта кнопка нажата, вызывается функция $scope.updateTime(), и после этого AngularJS вызывает $scope. $Digest(), так что привязки данных обновляются.

Вторая кнопка получает стандартный прослушиватель событий JavaScript, прикрепленный к ней изнутри функции контроллера. Когда нажимается вторая кнопка, выполняется функция слушателя. Как вы можете видеть, функции слушателя для обеих кнопок делают почти то же самое, но когда вызывается вторая функция прослушивания кнопки, привязка данных не обновляется. Это связано с тем, что $scope. $Digest() не вызывается после выполнения второго прослушивателя событий кнопки. Таким образом, если вы нажмете вторую кнопку, время будет обновлено в переменной $scope.data.time, но новое время никогда не будет отображаться.

Чтобы исправить это, мы можем добавить $scope. $digest() вызов последней строки прослушивателя событий кнопки, например:

document.getElementById("updateTimeButton")
    .addEventListener('click', function() {
console.log("update time clicked");
$scope.data.time = new Date();
$scope.$digest();
});

Вместо вызова $digest() внутри функции прослушивателя кнопки вы также могли бы использовать функцию $apply() следующим образом:

document.getElementById("updateTimeButton")
    .addEventListener('click', function() {
$scope.$apply(function() {
    console.log("update time clicked");
    $scope.data.time = new Date();
});
});

Обратите внимание, как функция $scope. $apply() вызывается изнутри прослушивателя событий кнопки и как обновление переменной $scope.data.time выполняется внутри функции, переданной как параметр в $apply() функция. Когда вызов функции $apply() заканчивается, AngularJS вызывает $digest() внутренне, поэтому все привязки данных обновляются.

+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос