AngularJS против jQuery
AngularJS и jQuery придерживаются совершенно разных идеологий. Если вы работаете с jQuery, некоторые отличия могут вас удивить. Angular может вас рассердить.
Это нормально, надо протолкнуться. Angular того стоит.
Большая разница (TL; DR)
jQuery предоставляет вам инструментарий для выбора произвольных битов DOM и внесения в них специальных изменений. Вы можете делать практически все, что захотите, по частям.
Вместо этого AngularJS предоставляет компилятор.
Это означает, что AngularJS читает всю вашу DOM сверху вниз и рассматривает ее как код, буквально как инструкции для компилятора. При обходе DOM он ищет определенные директивы (директивы компилятора), которые сообщают компилятору AngularJS, как себя вести и что делать. Директивы - это небольшие объекты, заполненные JavaScript, которые могут соответствовать атрибутам, тегам, классам или даже комментариям.
Когда компилятор Angular определяет, что часть DOM соответствует определенной директиве, он вызывает функцию директивы, передавая ей элемент DOM, любые атрибуты, текущую $ scope (которая является хранилищем локальных переменных) и некоторые другие полезные биты. Эти атрибуты могут содержать выражения, которые могут быть интерпретированы Директивой, и которые сообщают ей, как визуализировать и когда она должна перерисовываться.
Затем директивы могут, в свою очередь, включать дополнительные компоненты Angular, такие как контроллеры, службы и т. Д. То, что выходит в нижней части компилятора, - это полностью сформированное веб-приложение, подключенное и готовое к работе.
Это означает, что Angular основан на шаблоне. Ваш шаблон управляет JavaScript, а не наоборот. Это радикальная смена ролей и полная противоположность ненавязчивому JavaScript, который мы писали последние 10 лет или около того. К этому нужно привыкнуть.
Если это звучит так, как будто это может быть чрезмерно предписывающим и ограничивающим, ничто не может быть дальше от истины. Поскольку AngularJS обрабатывает ваш HTML как код, вы получаете детализацию уровня HTML в своем веб-приложении. Все возможно, и большинство вещей на удивление легко, если сделать несколько концептуальных прыжков.
Давайте перейдем к мелочам.
Во-первых, Angular не заменяет jQuery.
Angular и 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 и понять, что он делает. Он или она может вносить изменения. Это способ Angular.
Шаблон находится на водительском сиденье.
Один из первых вопросов, который я задавал себе при запуске AngularJS и просмотре руководств, - это «Где мой код?». Я не писал JavaScript, но все же у меня есть такое поведение. Ответ очевиден. Поскольку AngularJS компилирует DOM, AngularJS обрабатывает ваш HTML как код. Для многих простых случаев часто бывает достаточно просто написать шаблон и позволить AngularJS скомпилировать его в приложение за вас.
Ваш шаблон управляет вашим приложением. Он рассматривается как DSL. Вы пишете компоненты AngularJS, а AngularJS позаботится о том, чтобы их загрузить и сделать доступными в нужное время в зависимости от структуры вашего шаблона. Это сильно отличается от стандартного MVC. шаблон, где шаблон предназначен только для вывода.
Он больше похож на XSLT, чем на Ruby on Rails.
Это радикальная инверсия контроля, к которой нужно привыкнуть.
Перестаньте пытаться управлять своим приложением с помощью JavaScript. Пусть шаблон управляет приложением, а AngularJS позаботится о соединении компонентов вместе. Это тоже способ Angular.
Семантический 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. Модели существуют как атрибуты объекта с именем $ scope. Вы также можете хранить удобные служебные функции в $ scope, к которым затем будут иметь доступ ваши шаблоны.
- Представление - Ваши представления написаны в HTML. Представление обычно не является семантическим, потому что ваши данные находятся в модели.
- Контроллер - ваш контроллер - это функция JavaScript, которая подключает представление к модели. Его функция - инициализировать $ scope. В зависимости от вашего приложения вам может потребоваться создание контроллера. На странице может быть много контроллеров.
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 мы пишем директивы меньшего размера. Наша выпадающая директива была бы смехотворно маленькой. Он может поддерживать свернутое состояние и предоставлять методы для fold (), развертывания () или toggle (). Эти методы просто обновят $ scope.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. Если мы хотим делать исключения для каждого конкретного случая, шаблон упрощает это.
Закрытие против $ scope
Плагины JQuery создаются при закрытии. В рамках этого закрытия сохраняется конфиденциальность. Вы должны поддерживать свою цепочку областей видимости в рамках этого замыкания. У вас действительно есть доступ только к набору узлов DOM, переданных плагину с помощью jQuery, плюс любые локальные переменные, определенные в замыкании, и любые глобальные переменные, которые вы определили. Это означает, что плагины достаточно автономны. Это хорошо, но может иметь ограничения при создании всего приложения. Попытка передать данные между разделами динамической страницы становится рутиной.
AngularJS имеет объекты $ scope. Это специальные объекты, созданные и поддерживаемые AngularJS, в которых вы храните свою модель. Определенные директивы порождают новую $ scope, которая по умолчанию наследуется от своей оболочки $ scope, используя прототипное наследование JavaScript. Объект $ scope доступен в контроллере и в представлении.
Это умная часть. Поскольку структура наследования $ scope примерно соответствует структуре DOM, элементы имеют доступ к своей собственной области видимости и любым содержащим ее областям, вплоть до глобальной области $ scope (которая не совпадает с глобальной областью).
Это значительно упрощает передачу данных и их хранение на соответствующем уровне. Если раскрывающийся список развернут, только раскрывающийся список $ scope должен знать об этом. Если пользователь обновляет свои предпочтения, вы можете захотеть обновить глобальную $ scope, и все вложенные области, слушающие предпочтения пользователя, будут автоматически предупреждены.
Это может показаться сложным, на самом деле, если расслабиться, это похоже на полет. Вам не нужно создавать объект $ scope, 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, если мы хотим выполнить небольшую задачу, не связанную с dom, такую как получение канала из API, мы могли бы написать небольшую функцию для этого в нашем закрытии. Это правильное решение, но что, если мы хотим часто получать доступ к этому каналу? Что, если мы захотим повторно использовать этот код в другом приложении?
AngularJS предоставляет нам служебные объекты.
Сервисы - это простые объекты, содержащие функции и данные. Они всегда синглтоны, то есть их никогда не может быть больше одного. Скажем, мы хотим получить доступ к API переполнения стека, мы могли бы написать StackOverflowService
, который определяет методы для этого.
Допустим, у нас есть корзина для покупок. Мы могли бы определить ShoppingCartService, который поддерживает нашу корзину и содержит методы для добавления и удаления товаров. Поскольку служба является одноэлементной и совместно используется всеми другими компонентами, любой объект, которому необходимо, может записывать данные в корзину и извлекать из нее данные. Это всегда одна и та же тележка.
Сервисные объекты - это автономные компоненты AngularJS, которые мы можем использовать и повторно использовать по своему усмотрению. Это простые объекты JSON, содержащие функции и данные. Это всегда синглтоны, поэтому, если вы храните данные о сервисе в одном месте, вы можете получить эти данные где-то еще, просто запросив ту же услугу.
Внедрение зависимостей (DI) против Instatiation - также известное как де-спагеттификация
AngularJS управляет вашими зависимостями за вас. Если вам нужен объект, просто обратитесь к нему, и AngularJS получит его за вас.
Пока вы не начнете использовать это, трудно объяснить, насколько это огромная выгода для времени. Внутри jQuery нет ничего похожего на AngularJS DI.
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 (шаблоны, привязка данных, $ scope, директивы и т. Д.), Вы обнаружите, что вам нужно на намного меньше jQuery, чем могло бы потребоваться в противном случае.
Главное понимать, что ваш шаблон управляет вашим приложением. Перестаньте писать большие плагины, которые все делают. Вместо этого напишите небольшие директивы, которые делают одно, а затем напишите простой шаблон, чтобы связать их вместе.
Меньше думайте о ненавязчивом JavaScript и вместо этого думайте о расширениях HTML.
Моя маленькая книжка
Я был так взволнован AngularJS, что написал об этом небольшую книгу, которую вы можете прочитать в Интернете http://nicholasjohnson.com/angular-book/. Надеюсь, это поможет.
person
superluminary
schedule
12.05.2014