як працює зв’язування та перетравлення в AngularJS?


76

Одне, що відрізняє AngularJS від інших фреймворків JavaScript-MVC, - це здатність перетворювати пов'язані значення з JavaScript у HTML за допомогою прив'язок. Angular робить це "автоматично", коли ви присвоюєте будь-яке значення змінній $ scope.

Але наскільки це автоматично? Іноді Angular не піднімає зміну, тому мені потрібно зателефонувати $ scope. $ Apply () або $ scope. $ Digest (), щоб повідомити кутовий про отримання змін. Іноді, коли я запускаю будь-який із цих методів, він видає помилку і повідомляє, що дайджест уже триває.

Оскільки прив'язки (все, що знаходиться в фігурних дужках {{}} або атрибути ng), повторюються eval, то чи означає це, що Angular постійно опитує об'єкт $ scope для пошуку змін, а потім виконує eval для надсилання цих змін до DOM / HTML? Або AngularJS якимось чином розгадав використання магічних змінних, які запускають події, які запускаються, коли значення змінної змінюється або призначається? Я ніколи не чув про те, щоб він повністю підтримувався всіма браузерами, тож сумніваюся.

Як AngularJS відстежує свої прив'язки та змінні області?


5
Я знайшов корисним розділ у docs.angularjs.org/guide/concepts#runtime, який починається з "Ось пояснення того, як приклад Hello world досягає ефекту прив'язки даних".
Mark Rajcok,

3
Це повідомлення також корисно , якщо ви його ще не бачив: stackoverflow.com/questions/9682092/databinding-in-angularjs / ...
Gloopy

Прокоментуйте свій перший декларативний абзац: "здатність Angular перетворювати пов'язані значення з JavaScript у HTML за допомогою прив'язок" звучить як заплутаний спосіб сказати "прив'язка даних". І на даний момент часу це насправді не відрізняє Angular від інших фреймворків, таких як Ember або React. Питання корисне, не зрозумійте мене неправильно. Але цей перший абзац - це лише думка, з якою я випадково не погоджуюсь - я б відредагував питання, але я не відчуваю себе достатньо авторитетним.
Хорхе Орпінель

Відповіді:


64

На додаток до розділу документації, знайденого Марком, я думаю, ми можемо спробувати перерахувати всі можливі джерела змін.

  1. Взаємодія користувача з входами HTML ( 'текст' , 'номер' , 'url' , 'електронна пошта' , 'радіо' , 'прапорець' ). AngularJS має inputDirective . вводи "текст", "номер", "url" та "електронна пошта" прив'язують обробник слухача для подій "введення" або "введення клавіш". Обсяг викликів обробника слухачів . $ Apply . 'radio' та 'checkbox' прив'язують подібний обробник для події кліку.
  2. Взаємодія користувача з виділеним елементом. AngularJS має selectDirective з подібною поведінкою під час події "зміни".
  3. Періодичні зміни за допомогою служби очікування $ $, яка також робить $ rootScope. $ Apply () .
  4. eventDirectives (ngClick тощо) також використовують сферу застосування. $ apply .
  5. $ http також використовує $ rootScope. $ apply () .
  6. Зміни за межами світу AngularJS повинні використовувати сферу застосування. $ Застосовуйте, як відомо.

2
+1 для пункту "5. $ http також використовує $ rootScope. $ Apply ()." Арг. Хтось знає, чому вони це роблять? Це дуже дратує ...
gecco

5

Як ви виявили, це не опитування, а використання його внутрішнього циклу виконання, тому вам потрібно використовувати $ apply () або $ digest (), щоб запустити речі.

Пояснення Мішко є досить ґрунтовним, але трохи не вистачає того, що Angular просто намагається змусити $ scope повернутися до чіткого внутрішнього стану, коли що-небудь відбувається в його власному контексті. Це може зайняти досить багато стрибків між станами моделей, тому також тому ви не можете покладатися на те, що $ watch () спрацьовує лише один раз, а також тому, чому ви повинні бути обережними з налаштуванням відносин між моделями вручну, інакше ви потрапите в нескінченні кругові оновлення.


То як працює $ apply (someFn)? Чи буде виконано вміст someFn при виконанні ітерації застосування?
matsko

За допомогою $ apply код виконується в області Angular, тобто просто повідомити його про те, що ви хочете, щоб зміни були засвоєні
dain

У разі , якщо ви хочете , щоб запобігти зіткненню з $ перетравлюється, ви повинні перевірити $ фази: groups.google.com/d/msg/angular/FJwxJ-XbJaE/1NavZNQBhf4J
Дейн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.