"Мислення в AngularJS", якщо у мене є фон jQuery?

Припустимо, що я знайомий з розробкою клієнтських додатків в jQuery , але тепер я хотів би почати використовувати AngularJS . Чи можете ви описати зрушення парадигми, який необхідний? Ось кілька питань, які можуть допомогти вам сформувати відповідь:

  • Як мені створювати і створювати клієнтські веб-додатки по-іншому? Яка різниця?
  • Що я повинен припинити робити / використовувати; Що я повинен почати робити / використовувати замість цього?
  • Чи є які-небудь міркування / обмеження на стороні сервера?

Я не шукаю докладного порівняння між jQuery і AngularJS .

4523
21 февр. заданий Mark Rajcok 21 февр. 2013-02-21 07:09 '13 о 7:09 2013-02-21 7:09
@ 15 відповідей

1. Не створюйте свою сторінку, а потім міняйте її за допомогою DOM маніпуляції

В jQuery ви створюєте сторінку, а потім створюєте її динамічно. Це пов'язано з тим, що jQuery був розроблений для збільшення і неймовірно виріс з цієї простої причини.

Але в AngularJS ви повинні починати з нуля, маючи на увазі вашу архітектуру. Замість того, щоб думати, що "у мене є цей шматок DOM, і я хочу зробити це, зробіть X", ви повинні почати з того, що хочете, а потім приступити до розробки свого застосування, а потім, нарешті, приступити до розробки свого уявлення.

2. Не збільшуйте jQuery за допомогою AngularJS

Точно так само не починайте з ідеї, що jQuery виконує X, Y і Z, тому я просто додам AngularJS поверх цього для моделей і контролерів. Це дійсно заманливо, коли ви тільки починаєте, тому я завжди рекомендую, щоб нові розробники AngularJS взагалі не використовували jQuery, по крайней мере, до тих пір, поки вони не звикнуть до того, що робили "шлях Angular".

Я бачив багато розробників тут і в списку розсилки створюють ці складні рішення з плагінами jQuery з 150 або 200 рядків коду, які потім склеюються в AngularJS з набором зворотних викликів і $apply , які заплутують і заплутують; але в підсумку вони працюють! Проблема в тому, що в більшості випадках, коли плагін jQuery можна переписати в AngularJS у фрагменті коду, де раптово все стає зрозумілим і зрозумілим.

Суть в тому, що: при вирішенні проблеми спочатку "подумайте в AngularJS"; якщо ви не можете придумати рішення, запитаєте співтовариство; якщо після всього цього немає простого рішення, тоді не соромтеся звертатися до jQuery. Але не дозволяйте jQuery стати милицею, або ви ніколи не освоїте AngularJS.

3. Завжди думайте з точки зору архітектури

Спочатку відомо, що односторінкові додатки є додатками. Це не веб-сторінки. Тому нам потрібно думати, як розробник на стороні сервера, а не думати як клієнтський розробник. Ми повинні подумати про те, як розділити наш додаток на окремі, які розгортаються, тестовані компоненти.

Отже, як ви це робите? Як ви думаєте в AngularJS? Ось деякі загальні принципи, на відміну від jQuery.

Уявлення - це "офіційна запис"

В jQuery ми програмно міняємо уявлення. У нас може бути меню, що випадає, позначене як ul так:

Home </li> <li> <a href="#/menu1">Menu 1</a> <ul> <li><a href="#/sm1">Submenu 1</a></li> <li><a href="#/sm2">Submenu 2</a></li> <li><a href="#/sm3">Submenu 3</a></li> </ul> </li> <li> <a href="#/home">Menu 2</a> </li> </ul> 

В jQuery, в нашій логіці додатки, ми активували б його з чимось на зразок:

 <ul class="main-menu" dropdown-menu> ... </ul> 

Ці два роблять те ж саме, але у версії AngularJS будь-хто, хто дивиться на шаблон, знає, що має статися. Всякий раз, коли на борт приходить новий член команди розробників, вона може подивитися на це, а потім знати, що на ньому діє директива dropdownMenu ; їй не потрібно вводити правильну відповідь або просівати будь-який код. Погляд сказав нам, що мало статися. Набагато чистіше.

Розробники, нові для AngularJS, часто задають питання, як: як знайти всі посилання певного типу і додати на них директиву. Розробник завжди приголомшений, коли ми відповідаємо: ви цього не робите. Але причина, по якій ви цього не робите, це те, що це схоже на half-jQuery, half-AngularJS і нічого хорошого. Проблема тут в тому, що розробник намагається "виконати jQuery" в контексті AngularJS. Це ніколи не буде працювати добре. Подання - офіційний запис. Поза директиви (докладніше про це нижче) ви ніколи і ніколи не міняєте DOM. І директиви застосовуються в поданні, тому намір ясно.

Пам'ятайте: не створюйте, а потім відзначайте. Ви повинні архітектовать, а потім проектувати.

зв'язування даних

Це, безумовно, одна з найдивовижніших особливостей AngularJS, і вирізає багато необхідності робити види маніпуляцій з DOM, про які я згадував у попередньому розділі. AngularJS автоматично оновить ваше уявлення, щоб вам не довелося! В jQuery ми відповідаємо на події, а потім оновлюємо контент. Щось на зразок:

 <ul class="messages" id="log"> </ul> 

Крім проблем зі змішанням, у нас також є ті ж проблеми, що означають наміри, про які я згадав раніше. Але що більш важливо, нам довелося вручну посилатися і оновлювати DOM node. І якщо ми хочемо видалити запис в журналі, ми повинні також скопіювати код DOM. Як ми тестуємо логіку окремо від DOM? А що, якщо ми хочемо змінити презентацію?

Це трохи брудно і дрібниця тендітна. Але в AngularJS ми можемо це зробити:

 <ul class="messages"> <li ng-repeat="entry in log">{{ entry.msg }}</li> </ul> 

Але в цьому відношенні наш погляд може виглядати так:

поділ проблем і дає набагато більшу можливість перевірки.  Інші відповіді згадали цей момент, тому я просто залишу це на цьому. 

поділ проблем

І все вищеперелічене пов'язує цю складну тему: зберігайте свої проблеми роздільними. Ваша думка виступає в якості офіційного звіту про те, що має статися (здебільшого); ваша модель являє ваші дані; у вас є сервісний рівень для виконання багаторазових завдань; ви виконуєте маніпуляції з DOM і розширюєте своє уявлення за допомогою директив; і ви склеюєте все це разом з контролерами. Це також згадувалося в інших відповідях, і єдине, що я хотів би додати, відноситься до тестованості, про що я розповім в іншому розділі нижче.

включення залежностей

Щоб допомогти нам з поділом проблем, ін'єкція залежностей (DI). Якщо ви використовуєте серверний мова (від Java до PHP ), ви, ймовірно, вже знайомі з цією концепцією, але якщо ви є клієнтським хлопцем з jQuery, ця концепція може здатися чимось від дурного до зайвого до хіпстера. Але це не так.: -)

З широкої точки зору, DI означає, що ви можете вільно заявляти компоненти, а потім з будь-якого іншого компонента, просто попросите його екземпляр, і він буде наданий. Вам не обов'язково знати порядок завантаження, розташування файлів або щось в цьому роді. Сила може не відразу бути видимою, але я приведу тільки один (загальний) приклад: тестування.

Скажімо, в нашому додатку нам потрібна служба, яка реалізує серверне сховище через REST API і, в залежності від стану програми, локально зберігання також. При виконанні тестів на наших контролерах ми не хочемо зв'язуватися з сервером - ми все-таки тестуємо контролер. Ми можемо просто додати макет служби з тим же ім'ям, що і наш оригінальний компонент, і інжектор гарантуватиме, що наш контролер отримає підроблений один автоматично - наш контролер не знає і не повинен знати різницю.

Говорячи про випробування ...

4. Розробка, заснована на тестах - завжди

Це дійсно частина розділу 3 по архітектурі, але це так важливо, що я розміщую його в свій власний розділ верхнього рівня.

З усіх численних плагінів jQuery, які ви бачили, використовували або писали, скільки з них мало супутній набір тестів? Не дуже багато, тому що jQuery не надто піддається цьому. Але AngularJS є.

В jQuery єдиним способом тестування є створення компонента незалежно з зразковою / демонстраційної сторінкою, за допомогою якої наші тести можуть виконувати маніпуляції з DOM. Отже, ми повинні розвинути компонент окремо, а потім інтегрувати його в наш додаток. Як незручно! Так багато часу, при розробці за допомогою jQuery, ми вибираємо ітеративний варіант замість розробки, заснованої на тестах. І хто може звинуватити нас?

Але оскільки у нас є поділ проблем, ми можемо зробити тестове розвиток итеративно в AngularJS! Наприклад, скажімо, ми хочемо, щоб суперпростая директива вказувала в нашому меню, який наш поточний маршрут. Ми можемо заявити, що хочемо, з точки зору нашого застосування:

 

Добре, тепер ми можемо написати тест для неіснуючої директиви when-active :

 

І коли ми запускаємо наш тест, ми можемо підтвердити, що він зазнає невдачі. Тільки тепер ми повинні створити нашу директиву:

 .directive( 'myDirective', function () { return { template: '<a class="btn">Toggle me!</a>', link: function ( scope, element, attrs ) { var on = false; $(element).click( function () { on = !on; $(element).toggleClass('active', on); }); } }; }); 

В цьому є кілька помилок:

  • По-перше, jQuery ніколи не був потрібен. Тут ми нічого не зробили, що потрібно jQuery взагалі!
  • По-друге, навіть якщо у нас вже є jQuery на нашій сторінці, немає причин використовувати його тут; ми можемо просто використовувати angular.element , і наш компонент як і раніше буде працювати, коли ви потрапите в проект, у якого немає jQuery.
  • По-третє, навіть якщо припустити, що для цієї директиви потрібно jQuery, jqLite ( angular.element ) завжди буде використовувати jQuery, якщо він був завантажений! Тому нам не потрібно використовувати $ - ми можемо просто використовувати angular.element .
  • Четверте, тісно пов'язане з третім, полягає в тому, що елементи jqLite не повинні бути обгорнуті в $ - element , який передається функції link , вже буде елементом jQuery!
  • І по-п'яте, про які ми згадували в попередніх розділах, чому ми змішуємо матеріал шаблону в нашу логіку?

Ця директива може бути переписана (навіть для дуже складних випадків!) Набагато простіше:

7185
22 февр. відповідь дан Josh David Miller 22 февр. 2013-02-22 00:26 '13 в 0:26 2013-02-22 00:26

Імперативний → декларативний

В jQuery селектора використовуються для пошуку DOM , а потім прив'язують / реєструють оброблювачі подій. Коли подія запускається, цей (імперативний) код виконує оновлення / зміна DOM.

У AngularJS ви хочете думати про уявленнях, а не про елементах DOM. Уявлення (декларативні) HTML, що містять директиви AngularJS . Директиви налаштовують обробники подій за лаштунками для нас і дають нам динамічну прив'язку даних. Селектори рідко використовуються, тому потреба в ідентифікаторах (і деяких типах класів) значно зменшується. Уявлення прив'язані до моделей (через області). Уявлення - це проекція моделі. Моделі зміни подій (тобто Дані, властивості області) та подання, які проектують ці моделі, "автоматично".

У AngularJS подумайте про моделях, а не про обраних jQuery елементах DOM, які містять ваші дані. Подумайте про уявленнях як проекціях цих моделей, а не про реєстрацію зворотних викликів, щоб маніпулювати тим, що бачить користувач.

поділ проблем

jQuery використовує ненав'язливий JavaScript - поведінка (JavaScript) відокремлено від структури (HTML).

У AngularJS використовуються контролери і директиви (кожен з яких може мати свій власний контролер і / або компілювати і пов'язувати функції), щоб видалити поведінку з подання / структури (HTML). Angular також має служби і фільтри, щоб допомогти розділити / впорядкувати вашу програму.

border=0

Див. Також medican.site.site/questions/511 / ...

конструкція додатки

Один підхід до розробки програми AngularJS:

  • Подумайте про своїх моделях. Створіть служби або свої власні об'єкти JavaScript для цих моделей.
  • Подумайте, як ви хочете представити свої моделі - ваші погляди. Створюйте шаблони HTML для кожного уявлення, використовуючи необхідні директиви для отримання динамічної прив'язки даних.
  • Прикріпіть контролер до кожного виду (використовуючи ng-view і routing або ng-controller). Попросіть диспетчера знайти / отримати тільки будь-які дані моделі, які повинні виконувати уявлення. Зробіть контролери якомога більше тонкими.

прототипна спадкування

Ви можете багато чого зробити з jQuery, не знаючи про те, як працює прототипна спадкування JavaScript. При розробці додатків AngularJS ви уникнете деяких поширених помилок, якщо у вас є хороше розуміння успадкування JavaScript. Рекомендоване читання: Які нюанси обсягу прототипу / прототипного спадкування в AngularJS?

408
21 февр. відповідь дан Mark Rajcok 21 февр. 2013-02-21 07:09 '13 о 7:09 2013-02-21 7:09

AngularJS vs. jQuery

AngularJS і jQuery приймають абсолютно різні ідеології. Если вы отправляетесь из jQuery, вы можете обнаружить некоторые отличия от удивления. Angular может рассердить вас.