AngularJS vs. jQuery
AngularJS і jQuery приймають дуже різні ідеології. Якщо ви приїжджаєте з jQuery, вам можуть виявитись якісь відмінності. Кутовий може розлютити вас.
Це нормально, ви повинні просуватися. Кутовий того вартий.
Велика різниця (TLDR)
jQuery надає інструментарій для вибору довільних бітів DOM та внесення до них спеціальних змін. Ви можете робити майже все, що завгодно, детально.
AngularJS дає вам компілятор .
Це означає, що AngularJS читає весь ваш DOM зверху вниз і розглядає його як код, буквально як інструкції до компілятора. Під час обходу DOM він шукає конкретні директиви ( директиви компілятора), які розповідають компілятору AngularJS, як вести себе і що робити. Директиви - це невеликі об’єкти, повноті JavaScript, які можуть відповідати атрибутам, тегам, класам або навіть коментарям.
Коли кутовий компілятор визначає, що фрагмент DOM відповідає певній директиві, він викликає функцію директиви, передаючи їй елемент DOM, будь-які атрибути, поточний діапазон $ (що є локальним сховищем змінних) та деякі інші корисні біти. Ці атрибути можуть містити вирази, які можуть бути інтерпретовані Директивою, і які вказують, як відображати, і коли він повинен перемальовуватися.
Тоді директиви можуть у свою чергу втягувати додаткові кутові компоненти, такі як контролери, служби тощо. Що виходить внизу компілятора, - це повністю сформований веб-додаток, підключений до мережі та готовий до роботи.
Це означає, що Angular - це керований шаблон . Ваш шаблон керує JavaScript, а не навпаки. Це докорінне перетворення ролей і повна протилежність ненав'язливому JavaScript, про який ми писали останні 10 років. Це може зайняти деяке звикання.
Якщо це звучить так, що це може бути занадто призначальним і обмежуючим, нічого не може бути далі від істини. Оскільки AngularJS розглядає ваш HTML як код, ви отримуєте деталізацію рівня HTML у веб-програмі . Все можливо, і більшість речей напрочуд легко, коли ви зробите кілька концептуальних стрибків.
Давайте перейдемо до азотної крупки.
По-перше, Angular не замінює jQuery
Кутовий і jQuery роблять різні речі. AngularJS надає набір інструментів для створення веб-додатків. jQuery в основному надає інструменти для зміни DOM. Якщо jQuery присутній на вашій сторінці, AngularJS використовуватиме його автоматично. Якщо це не так, AngularJS постачається з jQuery Lite, що є скороченою, але все ще ідеально зручною версією jQuery.
Місько любить jQuery і не заперечує проти використання ним. Однак ви дізнаєтесь, що заздалегідь ви зможете отримати майже всю свою роботу, використовуючи комбінацію сфери, шаблонів та директив, і вам слід віддати перевагу цьому робочому процесу, де це можливо, оскільки ваш код буде більш дискретним, більш налаштованим та ін. Кутовий.
Якщо ви використовуєте jQuery, ви не повинні розповсюджувати його всюди. Правильне місце для маніпуляцій з DOM в AngularJS знаходиться в директиві. Детальніше про них пізніше.
Непомітний JavaScript з селекторами проти декларативних шаблонів
jQuery зазвичай застосовується ненав'язливо. Ваш код JavaScript пов'язаний у заголовку (або нижньому колонтитулі), і це єдине місце, про яке воно згадується. Ми використовуємо селектори для вибору бітів сторінки та написання плагінів для зміни цих частин.
JavaScript контролюється. HTML має абсолютно незалежне існування. Ваш HTML залишається смисловим навіть без JavaScript. Атрибути Onclick - це дуже погана практика.
Одне з перших, що ви помітите про AngularJS - це те, що спеціальні атрибути є скрізь . Ваш HTML буде завалений атрибутами ng, які по суті є атрибутами onClick на стероїдах. Це директиви (директиви компілятора) і є одним з головних способів приєднання шаблону до моделі.
Коли ви вперше побачите це, ви можете спокусити виписати AngularJS як нав'язливий JavaScript старої школи (як я робив спочатку). Насправді AngularJS не грає за цими правилами. У AngularJS ваш HTML5 - шаблон. Він складений AngularJS для створення вашої веб-сторінки.
Це перша велика різниця. Для jQuery, ваша веб-сторінка є DOM, яким слід маніпулювати. Для AngularJS ваш HTML - код, який слід зібрати. AngularJS читає всю вашу веб-сторінку і буквально компілює її на нову веб-сторінку, використовуючи вбудований її компілятор.
Ваш шаблон повинен бути декларативним; його значення повинно бути зрозумілим просто, прочитавши його. Ми використовуємо власні атрибути зі значущими іменами. Ми складаємо нові елементи HTML, знову ж таки із значущими іменами. Дизайнер з мінімальними знаннями HTML і відсутністю навичок кодування може прочитати ваш шаблон AngularJS і зрозуміти, що він робить. Він може вносити зміни. Це кутовий шлях.
Шаблон знаходиться у водійському сидінні.
Одне з перших запитань, яке я задав собі, коли запускав AngularJS і проходив підручники, - це "Де мій код?" . Я не написав JavaScript, і все ж маю таку поведінку. Відповідь очевидна. Оскільки AngularJS компілює DOM, AngularJS трактує ваш HTML як код. У багатьох простих випадках часто достатньо просто написати шаблон і дозволити AngularJS скласти його в додаток для вас.
Ваш шаблон визначає вашу програму. Це трактується як DSL . Ви пишете компоненти AngularJS, і AngularJS подбає про їх залучення та надання їх у потрібний час, виходячи зі структури вашого шаблону. Це дуже відрізняється від стандартного шаблону MVC , де шаблон призначений для виведення.
Наприклад, він більше схожий на XSLT, ніж Ruby on Rails .
Це радикальна інверсія контролю, до якої потрібно звикнути.
Перестаньте намагатися запускати свою програму зі свого JavaScript. Нехай шаблон запускає додаток, а AngularJS дбає про з'єднання компонентів разом. Це також кутовий спосіб.
Семантичні HTML проти семантичних моделей
З допомогою jQuery ваша HTML-сторінка повинна містити смисловий змістовний вміст. Якщо JavaScript вимкнено (користувачем чи пошуковою системою), ваш вміст залишається доступним.
Тому що AngularJS розглядає вашу HTML-сторінку як шаблон. Шаблон не повинен бути семантичним, оскільки ваш вміст, як правило, зберігається у вашій моделі, що в кінцевому підсумку походить від вашого API. AngularJS компілює ваш DOM з моделлю для створення семантичної веб-сторінки.
Ваше джерело HTML вже не є семантичним, натомість ваш API та компільований DOM є семантичним.
У AngularJS, що означає життя в моделі, HTML - це лише шаблон для відображення.
На даний момент у вас, швидше за все, виникають всілякі питання щодо SEO та доступності, і це правильно. Тут є відкриті питання. Більшість читачів екранів тепер будуть розбирати JavaScript. Пошукові системи також можуть індексувати вміст AJAXed . Тим не менш, ви хочете переконатися, що ви використовуєте URL-адреси pushstate і маєте гідну мапу сайту. Дивіться тут для обговорення питання: https://stackoverflow.com/a/23245379/687677
Розмежування проблем (SOC) проти MVC
Розділення проблем (SOC) - це закономірність, яка виросла за багато років веб-розробки з різних причин, включаючи SEO, доступність та несумісність браузера. Це виглядає приблизно так:
- HTML - смислове значення. HTML повинен стояти окремо.
- CSS - Стильний, без CSS сторінка все ще читається.
- JavaScript - поведінка, без сценарію вміст залишається.
Знову ж таки, AngularJS не грає за своїми правилами. Під час обведення AngularJS позбавляється десятиліття отриманої мудрості і замість цього реалізує шаблон MVC, в якому шаблон вже не є семантичним, навіть не трохи.
Це виглядає приблизно так:
- Модель - ваші моделі містять ваші смислові дані. Моделі, як правило, є об'єктами JSON . Моделі існують як атрибути об'єкта під назвою $ range. Ви також можете зберігати зручні функції утиліти в $ range, до яких потім можуть отримати доступ ваші шаблони.
- Перегляд - Ваші перегляди написані в HTML. Перегляд зазвичай не є семантичним, оскільки ваші дані живуть у моделі.
- Контролер - Ваш контролер - це функція JavaScript, яка підключає погляд на модель. Його функція полягає в ініціалізації $ області. Залежно від вашої програми, вам може знадобитися або не потрібно створювати контролер. Ви можете мати багато контролерів на сторінці.
MVC і SOC не знаходяться на протилежних кінцях одного масштабу, вони знаходяться на абсолютно різних осях. SOC не має сенсу в контексті AngularJS. Ви повинні його забути і рухатися далі.
Якщо, як я, ви пережили війни за браузер, ви можете вважати цю ідею досить образливою. Займіться, обіцяю.
Плагіни та директиви
Плагіни розширюють jQuery. AngularJS Директиви розширюють можливості вашого браузера.
У jQuery ми визначаємо плагіни, додаючи функції до jQuery.prototype. Потім ми підключаємо їх до DOM, вибираючи елементи та викликаючи плагін за результатом. Ідея полягає у розширенні можливостей jQuery.
Наприклад, якщо ви хочете карусель на своїй сторінці, ви можете визначити не упорядкований список фігур, можливо, загорнутий у елемент елемента наві. Потім ви можете написати jQuery, щоб вибрати список на сторінці, і перевстановити його як галерею з таймаутами, щоб зробити анімацію ковзання.
У AngularJS ми визначаємо директиви. Директива - це функція, яка повертає об'єкт JSON. Цей об’єкт повідомляє AngularJS, які елементи DOM шукати та які зміни для них внести. Директиви підключаються до шаблону, використовуючи або атрибути, або елементи, які ви вигадуєте. Ідея полягає у розширенні можливостей HTML новими атрибутами та елементами.
AngularJS спосіб - розширити можливості нативного HTML. Ви повинні написати HTML, схожий на HTML, розширений спеціальними атрибутами та елементами.
Якщо ви хочете карусель, просто використовуйте <carousel />
елемент, а потім визначте директиву для витягування шаблону та переконайтеся, що присоска працює.
Багато невеликих директив проти великих плагінів з перемикачами конфігурації
Тенденція jQuery полягає у написанні великих великих плагінів, таких як лайтбокс, які ми потім налаштовуємо, передаючи численні значення та параметри.
Це помилка в AngularJS.
Візьмемо приклад випадаючого. Під час написання плагіну, що випадає, вам може сподобатися кодування в обробниках кліків, можливо, функція, яку потрібно додати в шеврон, який знаходиться вгору або вниз, можливо, змінити клас розгорнутого елемента, показати приховати меню, всі корисні речі.
Поки не захочете зробити невелику зміну.
Скажіть, у вас є меню, яке ви хочете розгорнути на наведення курсору. Ну а тепер у нас проблема. Наш плагін є провідним для нашого обробника клацань, нам потрібно буде додати параметр конфігурації, щоб змусити його вести себе по-різному в цьому конкретному випадку.
У AngularJS ми пишемо менші директиви. Наша директива, що випадає, була б смішно малою. Він може підтримувати складений стан і надавати методи складання (), розгортання () або переключення (). Ці методи просто оновлюють $ range.menu.visible, що є булевим утримуванням держави.
Тепер у нашому шаблоні ми можемо підключити це:
<a ng-click="toggle()">Menu</a>
<ul ng-show="menu.visible">
...
</ul>
Потрібно оновити на курсорі миші?
<a ng-mouseenter="unfold()" ng-mouseleave="fold()">Menu</a>
<ul ng-show="menu.visible">
...
</ul>
Шаблон запускає додаток, тому ми отримуємо деталізацію на рівні HTML. Якщо ми хочемо робити винятки у кожному випадку, шаблон робить це легко.
Закриття порівняно з $
Плагіни JQuery створюються у закритому режимі. Конфіденційність зберігається під час закриття. Ви вирішуєте підтримувати ланцюг вашої сфери дії в рамках цього закриття. Ви дійсно маєте доступ до набору вузлів DOM, переданих у плагін jQuery, а також до будь-яких локальних змінних, визначених у закритті, та до будь-яких визначених вами глобальних глобалів. Це означає, що плагіни досить самодостатні. Це гарна річ, але може стати обмежувальним при створенні цілого додатка. Намагання передавати дані між розділами динамічної сторінки стає справою.
AngularJS має $ об’єкти. Це спеціальні об’єкти, створені та підтримувані AngularJS, в яких ви зберігаєте свою модель. Деякі директиви породжують нову область $ range, яка за замовчуванням успадковує свою обтікаючу область $ за допомогою прототипічного успадкування JavaScript. Об'єкт $ range доступний у контролері та представленні.
Це розумна частина. Оскільки структура успадковування $ діапазону приблизно відповідає структурі DOM, елементи мають доступ до власної сфери дії та будь-якого вмісту, що містить безперешкодно, аж до глобального діапазону $ (що не збігається з глобальним обсягом).
Це значно полегшує передачу даних та зберігання даних на відповідному рівні. Якщо спадне меню розгорнуте, про нього потрібно знати лише спадний діапазон $. Якщо користувач оновлює свої налаштування, можливо, ви захочете оновити глобальний діапазон $, і будь-які вкладені діапазони прослуховування налаштувань користувача автоматично будуть оповіщені.
Це може здатися складним, насправді, як тільки ви розслабитесь, це як політ. Вам не потрібно створювати об’єкт $ range, AngularJS створює і налаштовує його для вас, правильно та належним чином на основі ієрархії шаблону. Потім AngularJS робить доступним для вашого компонента, використовуючи магію введення залежності (докладніше про це пізніше).
Зміни DOM вручну та прив'язка даних
У jQuery ви вносите всі зміни DOM вручну. Ви конструюєте нові елементи DOM програмно. Якщо у вас є масив JSON і ви хочете поставити його в DOM, ви повинні написати функцію для генерації HTML та вставки.
У AngularJS ви також можете це зробити, але вам рекомендується використовувати прив'язку даних. Змініть свою модель, і оскільки DOM прив’язаний до неї за допомогою шаблону, ваш DOM автоматично оновлюватиметься, не потрібно втручатися.
Оскільки прив'язка даних здійснюється з шаблону, використовуючи атрибут або синтаксис фігурної дужки, це зробити дуже просто. З нею пов’язано мало пізнавальних накладних витрат, тож ви будете постійно робити це.
<input ng-model="user.name" />
Пов'язує вхідний елемент до $scope.user.name
. Оновлення вводу дозволить оновити значення у вашому поточному діапазоні, і навпаки.
Аналогічно:
<p>
{{user.name}}
</p>
виведе ім’я користувача в абзаці. Це пряма прив'язка, тому, якщо $scope.user.name
значення буде оновлено, шаблон також буде оновлений.
Аякс весь час
У jQuery здійснити дзвінок Ajax досить просто, але це все-таки щось, про що можна подумати. Існує додаткова складність для роздумів і неабиякий фрагмент сценарію для підтримки.
У AngularJS Ajax - це ваше стандартне рішення, яке відбувається за замовчуванням, і воно відбувається постійно, майже не помічаючи цього. Ви можете включати шаблони з ng-include. Ви можете застосувати шаблон із найпростішою спеціальною директивою. Ви можете зафіксувати дзвінок Ajax у сервісі та створити собі послугу GitHub або послугу Flickr , до якої ви можете отримати доступ з дивовижною легкістю.
Об'єкти обслуговування проти функцій помічника
У jQuery, якщо ми хочемо виконати невелике завдання, не пов’язане з домом, наприклад, витягнути канал з API, ми можемо написати невелику функцію для цього під час закриття. Це правильне рішення, але що робити, якщо ми хочемо часто отримувати доступ до цього каналу? Що робити, якщо ми хочемо використати цей код в іншій програмі?
AngularJS дає нам об’єкти обслуговування.
Послуги - це прості об'єкти, що містять функції та дані. Вони завжди одиночні, тобто ніколи їх не може бути більше. Скажімо, ми хочемо отримати доступ до API переповнення стека, ми можемо написати a, StackOverflowService
який визначає методи для цього.
Скажімо, у нас є кошик для покупок. Ми можемо визначити ShoppingCartService, який підтримує наш кошик і містить способи додавання та видалення елементів. Оскільки послуга є однотонною, і її поділяють усі інші компоненти, будь-який об’єкт, який потребує запису, може записувати в кошик для покупок і витягувати з нього дані. Це завжди один і той же візок.
Об'єкти обслуговування - це автономні компоненти AngularJS, які ми можемо використовувати та використовувати повторно, як вважаємо за потрібне. Вони є простими об'єктами JSON, що містять функції та дані. Вони завжди одиночні, тому якщо ви зберігаєте дані в сервісі в одному місці, ви можете отримати ці дані десь ще, просто запитуючи ту саму послугу.
Ін'єкційна залежність (DI) проти інсталяції - також деспагетизація
AngularJS управляє вашими залежностями для вас. Якщо ви хочете об'єкт, просто зверніться до нього, і AngularJS отримає його за вас.
Поки ви не почнете користуватися цим, важко пояснити, що це за масовий час. Нічого подібного AngularJS DI не існує всередині jQuery.
DI означає, що замість того, щоб писати свою програму і з'єднувати її разом, ви натомість визначаєте бібліотеку компонентів, кожен з яких ідентифікується рядком.
Скажіть, у мене є компонент під назвою "FlickrService", який визначає способи витягування каналів JSON з Flickr. Тепер, якщо я хочу написати контролер, який може отримати доступ до Flickr, мені просто потрібно посилатися на "FlickrService" по імені, коли я оголошу контролер. AngularJS подбає про інстанціювання компонента та надання його моєму контролеру.
Наприклад, тут я визначаю послугу:
myApp.service('FlickrService', function() {
return {
getFeed: function() { // do something here }
}
});
Тепер, коли я хочу скористатися цією послугою, я просто посилаюся на неї по імені так:
myApp.controller('myController', ['FlickrService', function(FlickrService) {
FlickrService.getFeed()
}]);
AngularJS визнає, що об'єкт FlickrService необхідний для екземпляра контролера, і надасть нам його.
Це робить проводку між собою дуже простою і в значній мірі виключає будь-яку схильність до спагетифікації. У нас є плоский список компонентів, і AngularJS передає їх нам один за одним як і коли вони нам потрібні.
Модульна архітектура сервісу
jQuery дуже мало говорить про те, як слід упорядкувати свій код. AngularJS має думки.
AngularJS дає вам модулі, в які ви можете розмістити свій код. Якщо ви пишете сценарій, який, наприклад, розмовляє з Flickr, ви можете створити модуль Flickr, щоб обернути всі ваші функції, пов'язані з Flickr. Модулі можуть включати інші модулі (DI). Ваша основна програма, як правило, є модулем, і вона повинна включати всі інші модулі, від яких буде залежати ваша програма.
Ви отримуєте просте повторне використання коду, якщо ви хочете написати іншу програму на базі Flickr, ви можете просто включити модуль Flickr і вуалу, у вас є доступ до всіх функцій, пов'язаних з Flickr, у вашій новій програмі.
Модулі містять компоненти AngularJS. Коли ми включаємо модуль, всі компоненти в цьому модулі стають нам доступними як простий список, ідентифікований їх унікальними рядками . Потім ми можемо вводити ці компоненти один одному, використовуючи механізм введення залежності AngularJS.
Підсумовуючи
AngularJS і jQuery не є ворогами. Можна дуже добре використовувати jQuery в AngularJS. Якщо ви добре використовуєте AngularJS (шаблони, прив'язка даних, $ range, директиви тощо), ви побачите, що вам потрібно набагато менше jQuery, ніж вам може знадобитися інакше.
Головне усвідомити, що ваш шаблон керує вашим додатком. Перестаньте намагатися писати великі плагіни, які все роблять. Натомість пишіть маленькі директиви, які роблять одне, а потім напишіть простий шаблон, щоб з'єднати їх.
Не думайте про ненав’язливий JavaScript, а замість цього роздумуйте над розширеннями HTML.
Моя маленька книжка
Я так захоплювався AngularJS, що написав про нього коротку книгу, яку ви дуже раді прочитати в Інтернеті http://nicholasjohnson.com/angular-book/ . Я сподіваюся, що це корисно.