Как происходит угловая привязка?

Ниже я понимаю, как происходит привязка в angularJS. Было бы здорово, если бы эксперты могли предоставить отзывы/комментарии.

<div ng-controller="ctrlA">
  {{myvar}}
  {{anothervar}}
</div>

$scope.watch( function (scope) {
    return scope.anothervar;
  } ,  function (oldValue, newValue) {
    // code to manupilate HTML with new value!!
  });

$scope.watch( function (scope) {
    return scope.myVar;
  } ,  function (oldValue, newValue) {
    // code to manipulate HTML with new value!!
  });

Как только angularJS встречает {{myVar}} (и {{anothervar}}), внутри создается наблюдатель (для каждой переменной). Этот наблюдатель создан для $scope контроллера 'ctrlA'.

Всякий раз, когда функции вызываются в пределах $timeout, ng-click и т. д., они встроены в $scope.apply(). После выполнения вашей функции (которая может изменить некоторые переменные области видимости) $apply вызовет дайджест в rootScope. Это синхронизирует переменные в приложении с пользовательским интерфейсом!

Когда вызывается $scope.digest, он выполняет итерацию по всем наблюдателям для этой области. Затем он получает текущее значение переменной и проверяет, изменилось ли оно. Если он изменился, он вызывает обработчик наблюдателя (который изменяет html, чтобы отразить новое значение!).

У меня есть вопрос. Есть ли в хранилище angularJS какая-то карта ключей (или какая-то структура данных) для каждой области, которая содержит ссылку на наблюдателя и текущее значение для этого наблюдателя? Что-то вроде:

watch ref (for myvar) -> current value (of myvar)
watch ref (for anothervar) -> current value (of anothervar)

person noi.m    schedule 23.07.2015    source источник
comment
Часть вашего ответа находится здесь: docs.angularjs.org/guide/scope#scope -жизненный цикл   -  person deostroll    schedule 23.07.2015


Ответы (1)


Ваше понимание того, как Angular настраивает наблюдатель для каждой привязки, в значительной степени соответствует действительности. Я продолжу и сразу перейду к вопросу, а не развенчиваю/обсуждаю вашу точку зрения на то, как выглядит внутренняя работа привязок Angular.

У меня есть вопрос. Есть ли в хранилище angularJS какая-то карта ключей (или какая-то структура данных) для каждой области, которая содержит ссылку на наблюдателя и текущее значение для этого наблюдателя?

$scope имеет внутренний массив текущих активных наблюдателей (.$$watchers), прикрепленных к указанной области, где запись будет выглядеть так:

введите здесь описание изображения

Приведенное ниже объяснение неверно. См. мою правку для исправлений

  • eq — это логическое значение, определяющее, является ли выражение в fn истинным/ложным.
  • exp — это необработанное строковое значение, которое вы представили в своем представлении между «волнистыми линиями» {{raw_expr_value}}.
  • Я полагаю, что fn является ссылкой на внутренний $interpolate.$$watchDelegate (или, как вы выразились, "ссылка на наблюдателя"). Если бы это было руководство $scope.$watch('val', _func_), fn было бы ссылкой на _func_.
  • get Я не совсем в этом уверен. Если бы кто-нибудь мог объяснить, что это такое, это было бы супер.
  • А last — это последнее значение, которое оценивается выражением.

Учитывая все вышесказанное, обычно вам не следует трогать внутренние переменные $$, но если вам необходимо — вперед. Держитесь осторожно :)


Редактировать

Я был неправ. Глядя на источник $watch , свойства следующие:

  • fn - функция обратного вызова для вашего наблюдателя.
  • last – источник и уникальное значение, применяемое в самом начале установки $watch. Вероятно, чтобы вызвать выражение для первоначальной оценки.
  • get — выражение, заключенное в $parse().
  • exp — prettyPrintExpression Я никогда не слышал об этом раньше. Возвращается к отслеживаемому выражению в обработчике представления/$watch.
  • eq – Здесь я был ох, очень не прав. Логическое значение определяет, делаем ли мы глубокое наблюдение (равенство объектов) или обычное поверхностное наблюдение.
person Kasper Lewau    schedule 23.07.2015
comment
Я играл с Angular prettyPrintExpression : кажется (начиная с 1.5.0), что он иногда содержит необработанное наблюдаемое выражение из привязки DOM. Бывший. ng-class="{active: $state.includes('profile')} вызовет часы с prettyPrintExpression={active: $state.includes('profile')}, но сложную функцию наблюдения в get / listener. Это определенно полезно для регистрации! (на что намекает красивая печать) - person Offirmo; 10.02.2016