$ наблюдаем () - это методобъекта Attributes , и поэтому он может использоваться только для наблюдения / наблюдения за изменением значения атрибута DOM. Он используется / вызывается только внутри директив. Используйте $ наблюдаем, когда вам нужно наблюдать / смотреть атрибут DOM, который содержит интерполяцию (т. Е. {{}}).
Например,attr1="Name: {{name}}"
, то в директиве:attrs.$observe('attr1', ...)
.
(Если вы пытаетесьscope.$watch(attrs.attr1, ...)
это не сработает из-за {{}} s - вы получите undefined
.) Используйте $ watch для всего остального.
$ watch () более сложный. Он может наблюдать / наблюдать «выражение», где выражение может быть либо функцией, либо строкой. Если выражение является строкой, этофункция $ parse 'd (то есть, оцененная как угловое выражение ) в функцию. (Именно эта функция вызывается в каждом цикле дайджеста.) Строковое выражение не может содержать {{}}. $ watch - это метод на объекта Scope , поэтому его можно использовать / вызывать везде, где у вас есть доступ к объекту области, следовательно, в
- контроллер - любой контроллер - созданный с помощью ng-view, ng-controller или директивного контроллера
- связующая функция в директиве, поскольку она также имеет доступ к области видимости
Поскольку строки оцениваются как угловые выражения, $ 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
) создает изолированную область. Каждая директива имеет одинаковые шесть атрибутов. Каждый атрибут является $ наблюдаемым и $ наблюдаемым.
<div d1 attr1="{{prop1}}-test" attr2="prop2" attr3="33" attr4="'a_string'"
attr5="a_string" attr6="{{1+aNumber}}"></div>
Посмотрите журнал консоли, чтобы увидеть различия между $ наблюдаем и $ наблюдать в функции связывания. Затем нажмите на ссылку и посмотрите, какие $ наблюдатели и $ watches запускаются изменениями свойств, сделанными обработчиком кликов.
Обратите внимание, что при запуске функции ссылки все атрибуты, содержащие {{}}, еще не оцениваются (поэтому, если вы попытаетесь проверить атрибуты, вы получите undefined
). Единственный способ увидеть интерполированные значения - это использовать $ наблюдаю (или $ наблюдаем, если используем изолированную область с '@'). Следовательно, получение значений этих атрибутов является асинхронной операцией. (И именно поэтому нам нужны функции $ наблюдений и $ наблюдений.)
Иногда вам не нужно $ наблюдать или смотреть. Например, если ваш атрибут содержит номер или логическое значение ( а не строки), просто оценить его однажды: attr1="22"
, то, скажем, в вашей связывающей функции: var count = scope.$eval(attrs.attr1)
. Если это просто константная строка - attr1="my string"
- тогда просто используйте attrs.attr1
в вашей директиве (нет необходимости в $ eval ()).
См. Также сообщение группы Google Войты о выражениях $ watch.