Angular VS jQuery

| Категории: AngularJS, jQuery
Анна Аминева

Иллюстрация блокнота

Ангуляр для jQuery разработчиков

Один из наиболее часто задаваемых вопросов при ангуляре - это то, как переключиться на AngularJS. Ведь до этого вы постоянно работали с jQuery, где ручная манипуляция деревом DOM – это обычная практика при добавлении интерактивности вашим веб страницам.

jQuery сам по себе – это набор утилит для упрощения работы с DOM. Это обертка вокруг действий с DOM, а не инструмент для построения веб приложений. Мы очевидно можем использовать jQuery, чтобы строить интерактивные сайты, но это тоже самое что и использовать молоток, чтобы рубить дерево… Почему бы не купить пилу для этих целей?

Эта статья расскажет вам о том, как думать в рамках Angular, не отказываясь от jQuery. Ведь jQuery - это библиотека с отличным инструментарием, которая процветала в течении долгих лет и может быть использована наряду с AngularJS в наших приложениях.

Мы пройдемся по тому, как думать в ангуляре и вместе смоделируем состояние разума для структурирования наших находок о том как создавать более быстрые, стабильные и хорошие веб-приложения вместе с AngularJS.
На протяжение всей статьи мы работаем с jQuery приложением и показываем вам как построить его же, но с помощью Angular.

Как мы разрабатываем веб-приложения с jQuery

1
2
3
4
5
$(document).ready(function() {
$("#article").click(function(evt) {
$("#article_placeholder").append("Angular for the jQuery developer");
});
});

Исторически сложилось, что от нас, разработчиков, всегда требовалось вручную обновлять элементы DOM для построения динамичной веб-страницы.

Сначала мы создаем структуру нашего веб сайта, затем изменяем дизайн компонентов в CSS и добавляем интерактивность на страницу. Таким образом, мы как бы наслаиваем интерактивность на наш HTML код как запоздалое дополнение и принимаем интерактивность как что-то второсортное.

Почему не jQuery для разработки веб- приложений?

Во всем исходном коде мы постоянно создаем действия для конкретных элементов с конкретными идентификаторами. Что если член команды утверждает, что название message не достаточно точное? Мы полностью меняем DOM, чтобы соответствовать новому дизайну или мы добавляем новый функционал, который включает идентификатор name?

Тесная связь

Javascript написан для того, чтобы соответствовать нашему HTML. Такое тесное взаимодействие часто требует от нас проделывать больше работы, чтобы оставлять наши данные синхронизированными с их отображением. Когда бы мы не меняли DOM, мы должны быть достаточно деликатными и уверенными в том, что мы не испортим функциональность, добавленную javascript.

Беспорядок в коде

При использовании jQuery нет четкой структуры организации нашего веб приложения; нам постоянно приходится решать этот вопрос.

Низкоуровневые инструменты для высокоуровневой функциональности

Когда мы строим веб приложение с любой степенью сложности, нас заставляют раз за разом создавать собственные обработчики определенных действий, используя низкоуровневые инструменты для манипуляции DOM, вместо того, чтобы фокусироваться на функциональности.

Angular использует другой подход к построению веб приложений: он воспринимает создание интерактивности как родной компонент веб-приложений и поощряет ее создание в течение всего рабочего процесса над приложением.

Следующие 8 идей всегда держите в голове, когда строите Angular приложения:

1) Добавляйте интерактивность к странице прямо в ее разметке

Когда мы пишем наши приложения на Angular, мы не разделяем то, как мы создаем разметку страницы и описываем взаимодействия с ней; мы определяем функциональность прямо в html. Если мы хотим произвести действие после нажатия на кнопку, то мы прикрепляем действие прямо к кнопке:

1
2
<!-- Call the runAction() method -->
<button ng-click="runAction()">Run action</button>

Это позволяет нам делать код понятным и декларативным. В добавок DOM нам явно говорит, что он сделает в браузере.

Императивное программирование: говорить «машине» как что-то сделать и, в результате, все что вы хотите, чтобы случилось - случится.

Декларативное программирование: говорить «машине» что вы хотите сделать и давать компьютеру разобраться с тем, как это сделать.

2) Оставьте DOM в покое

Angular очень понятно описывает стратегию создания приложений с использованием данных для создания функциональности. Вместо того, чтобы создавать страницу, которой мы будем манипулировать, мы взаимодействуем непосредственно с объектом данных (называемым $scope).
Когда мы захотим поменять элемент в нашем виде, мы поменяем данные, которые привязаны к нему и позволим Angular разбираться с обновлением DOM.

1
2
3
4
5
6
<!-- Show the name in the browser -->
<h1>Welcome {{ name }}</h1>
<!-- Bind the input to the name -->
<input ng-model="name"
name="name"
placeholder="Enter your name" />

Добро пожаловать

Ни при каких условиях в этом примере мы не должны напрямую изменять DOM. Этот факт позволяет нам создавать и проектировать HTML одновременно.

3) Создание архитектуры приложения

Создание Angular приложения позволяет нам думать с точки зрения построения самого приложения. Мы можем сфокусироваться на функциональности, начиная с понимания того как приложение взаимодействует с серверным АПИ, и заканчивая тем какое действие должно произойти когда мы нажмем на кнопку.
Мы должны думать о том, как разделить функционал нашего приложения на маленькие компоненты, которые позволяют легко расширять и тестировать наше приложение.

4) Оставим jQuery безучастным

Заманчиво использовать jQuery в качестве опорного звена, когда мы только начинаем изучать Angular. Но мы настоятельно рекомендуем вообще не загружать jQuery, когда вы начинаете работать с Angular.
Все, что мы делаем с jQuery, можно также создать с Angular, но чаще всего, с меньшим количеством кода.
Используя Angular и не используя привычные инструменты как костыли, мы сделаем наш код более эффективным, расширяемым и тестируемым. Если вы хотите создать кусочек функциональности, которой нет в ангуляре, то скорее всего кто-то в сообществе разработчиков это уже сделал.

5) Вид – ядро приложения

Angular приложения используют вид как контейнер для интерактивности и данных. Мы используем директивы для добавления функциональности к отображению, которое, в свою очередь, использует привязывание данных для создания явных цепочек действия внутри приложения.

1
2
3
4
<div fs-modal
on-ok="proceedAsPlanned()"
on-cancel="abort()"
title="Are you sure?"></div>

Директива fs-modal, использованная, выше отчетливо демонстрирует, какие задачи выполняет элемент div. В отличии от неприятной ситуации, когда мы добавляем функционал во внешнем документе, единственный способ изменить выполняемые видом задачи - это изменить HTML код.

6) Модели обновляют вид, который обновляет модели.

Один из наиболее базовых и крутых особенностей Angular- это то, что нам не нужно беспокоиться о DOM после того, как мы создали HTML разметку.

В отличии от jQuery, в котором нам нужно императивно создавать элементы и прикреплять их, в то же время поддерживать состояние документа или искать элементы в нем уже непосредственно во время выполнения программы, мы можем сосредоточиться на построении функционала, основанном на ожидаемых данных.

К примеру, чтобы показать индикатор загрузки, мы можем установить булев флаг, который показывает или скрывает элемент, основываясь на значении модели:

1
2
3
<div ng-show="isLoading">
<img src="/images/loading.gif" />
</div>

Теперь, когда мы загружаем наши данные, мы можем включить этот «переключатель» ( делая isLoading равным true). Когда мы закончим с загрузкой данных, мы можем переключить значение модели обратно в false и индикатор будет спрятан.

1
2
3
4
5
6
7
8
9
10
11
$scope.loadNewData = function() {
$scope.isLoading = true;
$http.get('/api/data.json')
.success(function(data) {
$scope.data = data;
$scope.isLoading = false;
})
.error(function(reason) {
$scope.isLoading = false;
});
}

Попробуйте Данный код включит isLoading на 2 секунды, но не будет загружать никаких данных на самом деле Load new data
Если мы обновим модель в наших контроллерах, тогда и вид будет обновлен. Если мы меняем и воздействуем на модель в виде на экране, то модель в наших контроллерах также будет обновлена и все останется синхронизированным.

Магия Angular в том, что на протяжении всего процесса у нас вообще не должен возникать вопрос как, мы можем просто заниматься созданием требуемого функционала.

7) Зависимости, зависимости и зависимости - о, Господи!

Другая задача, которую Ангуляр отлично выполняет за нас в фоне - это внедрение зависимостей. Мы просто говорим Ангуляру, какие зависимости нам нужны и если Ангуляр сможет их найти, то он выполнит их загрузку за нас.

8) Разработка через тестирование

Одной из лучших составляющих частей Ангуляра является то, что он с нуля был задуман так, чтобы быть тестируемым. Когда будем писать тесты, мы не только гарантируем то, что наше приложение будет работать, но и то, что компоненты, которые мы используем, будут работать как следует.

Когда создавали ангуляр, то разработка через тестирование всегда являлась одной из основных парадигм фреймворка. Именно поэтому писать тесты для приложений на ангуляре так просто.

Мы можем писать тесты для всех частей приложения - для моделей, сервисов, видов и т.д.
Мы можем проводить тестирование как со стороны разработчика (используя юнит-тестирование каждого компонента), так и со стороны конечных пользователей (используя интегрированное тестирование, где мы загружаем наше приложение в браузер и говорим тестируему фрейворку нажать на кнопки и тестировать, тогда вид показывает то, что мы ожидаем).

На заметку Никаких больше нажатий кнопок вручную каждый раз, когда мы вносим незначительное изменение для того, чтобы протестировать работает ли что-нибудь.

В заключение

Когда мы думаем в терминах Ангуляра, мы думаем о:

• Видах, не о DOM элементах
• Директивах, не о привязках действий
• Моделях как о проекциях видов
• Функциональном разделении

Чат приложение на jQuery

Например, предположим у нас есть простое чат приложение, созданное с помощью jQuery. Приложение невероятно простое и имеет следующие особенности:
• Позволяет пользователям вводить свое никнейм

• Позволяет пользователям вводить сообщение и отправлять его получателям- подписчикам чата.

• Показывать список пользователей, связанных с нашим чат приложением

Приложение, которое мы будем создавать имеет следующую HTML структуру (с убранными стилями для упрощения)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div id="chatApp" class="row">
<div id="message_placeholder"></div>
<form action="#">
<input type="text"
id="name"
placeholder="Your name" />
<input type="text"
id="message"
placeholder="Your message..."/>
<input type="submit"
class="button prefix"
value="Send" />
</form>
</div>
</div>

У нас есть форма с несколькими полями для ввода и div, который будет содержать список сообщений.

Живой пример с jQuery

Чтобы построить это приложение с jQuery, нам потребуются несколько важных кусков информации. Нам нужно знать айди следующих полей для ввода:

• Поле ввода никнейма (#name)

• Поле ввода сообщения (#message)

• Окно чата (#message_placeholder)

Для этого поля мы присоединим слушателя событий отправки формы. В нем будем обрабатывать добавление сообщений в чат.
Внутри окна чата, мы будем держать лишь ограниченное количество сообщений в истории, так что нам нужно удостовериться, что мы удаляем старые сообщения.
И последнее, мы сможем запустить весь процесс только после того, как документ будет готов к запуску, так что понадобиться обернуть весь код в $(document).ready(function() {}).
Так как это не руководство по jQuery, то вот исходный код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$(document).ready(function() {
var maxMessages = 5,
messageBox = $("#message_placeholder");
$("#chatApp form").on('submit', function(evt) {
var from = $("#name").val() || "Anonymous",
msg = $("#message").val()
var msg = $("<div />").text(from+": "+msg);
messageBox.append(msg);
$("#message").val("");
if (messageBox.children().length > maxMessages)
messageBox.children("div").first().remove();
return false;
});
});

Создаем чат на Ангуляре

Когда мы создаем ту же чат программу с Ангуляром, нам не нужно беспокоиться о том, знаем ли мы селекторы для элементов, которые мы используем для добавления интерактивности, потому что мы будем создавать наш DOM так, чтобы он уже включал всю интерактивность.
Как и во всех приложениях, написанных на Angular, мы начнем с создания нашего приложения, непосредственно в HTML странички. Angular приложения могут и не занимать всю станицу, они могут располагаться в конкретных элементах, используя ng-app директиву. Также нам потребуется описывать наш функционал внутри контроллеров, чтобы мы не загрязняли глобальную область видимости.
<div ng-app="ngChatApp" ng-controller="ChatCtrl"> </div>

На заметку Директива - это просто замысловатый термин для функции, которая запускается вконтексте конкретного DOM элемента. Это позволяет нам добавлять функционал непосредственно к HTML элементам.
Далее, мы напишем немного JavaScript кода, который будем использовать для создания нашего функционала:

1
2
3
4
angular.module('ngChatApp', [])
.controller('ChatCtrl', function($scope) {
// Write our controller here
});

Все дело в данных, а не в DOM

Нам надо только подумать о том, какие данные мы хотим поместить в наш HTML и где, не беспокоясь о том, как они туда попадают. Помня об этом, мы будем отслеживать объект с сообщениями для отображения, а не элементы DOM.
В нашем виде, мы можем просто пройтись по массиву наших сообщений и позволить DOM отобразить их, что он и сделает, когда массив заполнится данными:

1
2
3
4
5
<div id="message_placeholder">
<div ng-repeat="message in messages">
{{ message.from }}: {{ message.msg }}
</div>
</div>

Подобным образом, мы можем привязывать значение модели к нашим полям ввода и позволить модели быть созданной в фоне таким образом, чтобы мы смогли использовать ее же в рамках действий в нашем контроллере. Мы так же можем привязать действия, такие как отправка формы, прямо в HTML.

1
2
3
4
5
6
7
8
9
10
<form ng-submit="addMessage()">
<input type="text"
ng-model="username"
placeholder="Your name" />
<input type="text"
ng-model="message"
placeholder="Your message" />
<input type="submit"
value="Send" />
</form>

Когда форма отправлена, функция addMessage()будет вызвана и у значения username и message будут доступны нам… но где же мы можем их получить?

##$scope
$scope – это «клей» между видом и контроллером. Все, что мы привязываем к виду станет доступным в $scope контроллера и наоборот. Таким образом, мы можем просто изменять массив сообщений в нашем scope, изменится и вид.

Функция addMessage()выглядит таким образом:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
angular.module('ngChatApp', [])
.controller('ChatCtrl', function($scope) {
var maxMessages = 5;
$scope.messages = [];
$scope.addMessage = function() {
$scope.messages.push({
from: $scope.username,
msg: $scope.message
});
if ($scope.messages.length > maxMessages)
$scope.messages.splice(0,1);
$scope.message = "";
}
});

##Ага, это все!
Ангуляр позаботится о загрузке данных из модели в DOM и отрисует наш вид.

По мотивам “Angular for the jQuery developer” для http://www.ng-newsletter.com