$ obser () - метод наоб'єкті Attributes , і як такий він може використовуватися лише для спостереження / перегляду зміни значення атрибута DOM. Він застосовується / називається всередині директив. Використовуйте $ obser, коли вам потрібно спостерігати / переглядати атрибут DOM, який містить інтерполяцію (тобто {{}} 's).
Наприклад,attr1="Name: {{name}}"
, то в директиві:attrs.$observe('attr1', ...)
.
(Якщо ви спробуєте,scope.$watch(attrs.attr1, ...)
це не спрацює через {{}} s - ви отримаєтеundefined
.) Використовуйте $ watch для всього іншого.
$ watch () складніше. Він може спостерігати / спостерігати за «виразом», де вираз може бути або функцією, або рядком. Якщо вираз є рядком, це $ parse 'd (тобто оцінюється як кутовий вираз ) у функцію. (Саме ця функція називається кожним циклом дайджесту.) Виразний рядок не може містити {{}} 's. $ watch - це метод наоб'єкті Scope , тому його можна використовувати / викликати, де б ви не мали доступу до об'єкта області, отже, у
- контролер - будь-який контролер - один, створений через ng-view, ng-контролер або контролер
- функція зв'язування в директиві, оскільки вона має доступ і до сфери застосування
Оскільки рядки оцінюються як кутові вирази, $ watch часто використовується, коли потрібно спостерігати / дивитися властивість моделі / області застосування. Наприклад, attr1="myModel.some_prop"
у функції контролера або зв'язку: scope.$watch('myModel.some_prop', ...)
або scope.$watch(attrs.attr1, ...)
(або scope.$watch(attrs['attr1'], ...)
).
(Якщо ви спробуєте, attrs.$observe('attr1')
ви отримаєте рядок myModel.some_prop
, який, мабуть, не є тим, що ви хочете.)
Як було обговорено в коментарях до відповіді @ PrimosK, всі $ спостереження та $ годинники перевіряються кожен цикл дайджесту .
Директиви з ізоляційними сферами складніші. Якщо використовується синтаксис '@', ви можете $ спостерігати або $ спостерігати атрибут DOM, який містить інтерполяцію (тобто {{}}). (Причина, яка працює з $ watch, полягає в тому, що синтаксис '@' робить інтерполяцію для нас, отже, $ watch бачить рядок без {{}}). $ дотримуйтесь і для цього випадку.
Щоб допомогти перевірити все це, я написав Plunker, який визначає дві директиви. Один ( d1
) не створює нового розмаху, інший ( d2
) створює область ізоляції. Кожна директива має однакові шість атрибутів. Кожен атрибут є як $ obser'd, так і $ watch'ed.
<div d1 attr1="{{prop1}}-test" attr2="prop2" attr3="33" attr4="'a_string'"
attr5="a_string" attr6="{{1+aNumber}}"></div>
Подивіться на журнал консолі, щоб побачити відмінності між $ observer і $ watch у функції зв’язку. Потім перейдіть за посиланням і перегляньте, які $ спостереження та $ годинник викликані змінами властивості, здійсненими обробником кліків.
Зауважте, що при запуску функції посилання будь-які атрибути, які містять {{}}, ще не оцінені (тому, якщо ви спробуєте вивчити атрибути, ви отримаєте undefined
). Єдиний спосіб побачити інтерпольовані значення - це використовувати $ obser (або $ watch, якщо використовується область ізоляції з '@'). Тому отримання значень цих атрибутів є асинхронною операцією. (І саме тому нам потрібні функції $ watch і $ watch.)
Іноді вам не потрібно $ спостерігати або $ watch. Наприклад, якщо ваш атрибут містить номер або логічне значення ( а не рядки), просто оцінити його одного разу: attr1="22"
, то, скажімо, в вашій зв'язує функції: var count = scope.$eval(attrs.attr1)
. Якщо це просто постійний рядок - attr1="my string"
- тоді просто використовуйте attrs.attr1
у своїй директиві (не потрібно $ eval ()).
Дивіться також публікацію в гуртовій групі Vojta про вирази $ watch.