Я знаю, что оба Watchers
и Observers
вычисляются как только что-то $scope
меняется в AngularJS. Но не мог понять, в чем именно разница между этими двумя.
Мое первоначальное понимание состоит в том, что Observers
они вычисляются для угловых выражений, которые являются условиями на стороне HTML, где Watchers
выполняются при выполнении $scope.$watch()
функции. Я правильно думаю?
javascript
angularjs
Abilash
источник
источник
Ответы:
$ наблюдаем () - это методобъекта Attributes , и поэтому он может использоваться только для наблюдения / наблюдения за изменением значения атрибута DOM. Он используется / вызывается только внутри директив. Используйте $ наблюдаем, когда вам нужно наблюдать / смотреть атрибут DOM, который содержит интерполяцию (т. Е. {{}}).
Например,
attr1="Name: {{name}}"
, то в директиве:attrs.$observe('attr1', ...)
.(Если вы пытаетесь
scope.$watch(attrs.attr1, ...)
это не сработает из-за {{}} s - вы получитеundefined
.) Используйте $ watch для всего остального.$ watch () более сложный. Он может наблюдать / наблюдать «выражение», где выражение может быть либо функцией, либо строкой. Если выражение является строкой, этофункция $ parse 'd (то есть, оцененная как угловое выражение ) в функцию. (Именно эта функция вызывается в каждом цикле дайджеста.) Строковое выражение не может содержать {{}}. $ watch - это метод на объекта Scope , поэтому его можно использовать / вызывать везде, где у вас есть доступ к объекту области, следовательно, в
Поскольку строки оцениваются как угловые выражения, $ watch часто используется, когда вы хотите наблюдать / наблюдать свойство model / scope. Например,
attr1="myModel.some_prop"
затем в функции контроллера или связи:scope.$watch('myModel.some_prop', ...)
илиscope.$watch(attrs.attr1, ...)
(илиscope.$watch(attrs['attr1'], ...)
).(Если вы пытаетесь
attrs.$observe('attr1')
вы получите строкуmyModel.some_prop
, которая, вероятно, не то, что вы хотите.)Как уже говорилось в комментариях к ответу @ PrimosK, все $ Наблюдения и $ watches проверяются каждый цикл дайджеста .
Директивы с изолированными областями более сложны. Если используется синтаксис '@', вы можете $ наблюдать или $ смотреть атрибут DOM, который содержит интерполяцию (т. Е. {{}}). (Причина, по которой он работает с $ watch, заключается в том, что синтаксис '@' выполняет для нас интерполяцию , поэтому $ watch видит строку без {{}}.) Чтобы упростить запоминание того, что использовать, когда я предлагаю использовать Наблюдать за этим делом тоже.
Чтобы проверить все это, я написал Plunker, в котором определены две директивы. One (
d1
) не создает новую область, другой (d2
) создает изолированную область. Каждая директива имеет одинаковые шесть атрибутов. Каждый атрибут является $ наблюдаемым и $ наблюдаемым.Посмотрите журнал консоли, чтобы увидеть различия между $ наблюдаем и $ наблюдать в функции связывания. Затем нажмите на ссылку и посмотрите, какие $ наблюдатели и $ watches запускаются изменениями свойств, сделанными обработчиком кликов.
Обратите внимание, что при запуске функции ссылки все атрибуты, содержащие {{}}, еще не оцениваются (поэтому, если вы попытаетесь проверить атрибуты, вы получите
undefined
). Единственный способ увидеть интерполированные значения - это использовать $ наблюдаю (или $ наблюдаем, если используем изолированную область с '@'). Следовательно, получение значений этих атрибутов является асинхронной операцией. (И именно поэтому нам нужны функции $ наблюдений и $ наблюдений.)Иногда вам не нужно $ наблюдать или смотреть. Например, если ваш атрибут содержит номер или логическое значение ( а не строки), просто оценить его однажды:
attr1="22"
, то, скажем, в вашей связывающей функции:var count = scope.$eval(attrs.attr1)
. Если это просто константная строка -attr1="my string"
- тогда просто используйтеattrs.attr1
в вашей директиве (нет необходимости в $ eval ()).См. Также сообщение группы Google Войты о выражениях $ watch.
источник
ng-src/ng-href
использоватьattr.$observe
вместоscope.$watch
этого?@
синтаксиса. Я считаю, что нет разницы в производительности (но я не смотрел на фактический исходный код).Если я правильно понимаю ваш вопрос, вы спрашиваете, в чем разница, если вы регистрируете обратный вызов слушателя в
$watch
или если вы делаете это с$observe
.Обратный звонок, зарегистрированный с
$watch
, запускается, когда$digest
выполнении.Обратный
$observe
вызов, зарегистрированный в, вызывается при изменении значения атрибутов, которые содержат интерполяцию (напримерattr="{{notJetInterpolated}}"
).Внутри директивы вы можете использовать их оба очень похожим образом:
или
источник
$digest
фазе, можно с уверенностью предположить, что$observe
обратный вызов будет вызван$digest
. И$watch
обратный вызов также будет вызываться,$digest
но всякий раз, когда значение изменяется. Я думаю, что они делают ту же самую работу: «наблюдайте за выражением, вызывайте обратный вызов, значение меняется». Разница в ключевых словах, возможно, просто синтаксический сахар, чтобы не запутывать разработчика.Я думаю, что это довольно очевидно:
Имейте в виду : обе функции имеют два аргумента,
function (oldValue, newValue)
Я сделал plunker, так что вы можете понять, как их использование. Я использовал аналогию с Хамелеоном, чтобы сделать изображение проще.
источник
Почему $ наблюдение отличается от $ watch?
WatchExpression оценивается и сравнивается с предыдущим значением в каждом цикле digest (), если в значении watchExpression есть изменение, вызывается функция watch.
$ Наблюдение является специфическим для отслеживания интерполированных значений. Если значение атрибута директивы интерполировано, например,
dir-attr="{{ scopeVar }}"
, функция наблюдения будет вызываться только тогда, когда установлено интерполированное значение (и, следовательно, когда $ digest уже определил, необходимо выполнить обновления). По сути, уже есть наблюдатель для интерполяции, и функция $ наблюдайте за этим.Смотрите $ наблюдаю и $ устанавливаем в compile.js
источник