Ангуляр с чего начать
Учебник AngularJS: Всеобъемлющее руководство, часть 1
Содержание
1 Введение в AngularJS
Angular – MVW-фреймворк для разработки качественных клиентских веб-приложений на JavaScript. Он создан и поддерживается в Google и предлагает взглянуть на будущее веба, на то, какие новые возможности и стандарты он готовит для нас.
MVW означает Model-View-Whatever (модель – вид – что угодно), то есть гибкость в выборе шаблонов проектирования при разработке приложений. Мы можем выбрать модели MVC (Model-View-Controller) или MVVM (Model-View-ViewModel).
Этот обучающий материал задумывался как отправная точка для изучения AngularJS, его концепций и API, чтобы помочь вам создавать великолепные веб-приложения современным способом.
AngularJS позиционирует себя как фреймворк, улучшающий HTML. Он собрал концепции из разных языков программирования, как JavaScript, так и серверных, и делает из HTML также нечто динамическое. Мы получаем подход, основанный на данных, к разработке приложений. Нет нужды обновлять Модель, DOM или делать какие-то другие затратные по времени операции, например, исправлять ошибки браузеров. Мы концентрируемся на данных, данные же заботятся об HTML, а мы просто занимаемся программированием приложения.
Инженерные концепции в фрейморках JavaScript
Позиция AngularJS по работе с данными и другими инженерными концепциями отличается от таких фреймворков, как Backbone.js and Ember.js. Мы довольствуемся уже известным нам HTML, а Angular самостоятельно его улучшает. Angular обновляет DOM при любых изменениях Модели, которая живёт себе в чистых Объектах JavaScript с целью связи с данными. Когда обновляется Модель, Angular обновляет Объекты, которые содержат актуальную информацию о состоянии приложения.
2.1 MVC и MVVM
Если вы привыкли делать статичные сайты, вам знаком процесс создания HTML вручную, кусочек за кусочком, когда вы вписываете в страницу нужные данные и повторяете сходные части HTML снова и снова. Это могут быть столбцы решётки, структура для навигации, список ссылок или картинок, и т.п. Когда меняется одна маленькая деталь, приходится обновлять весь шаблон, и все последующие его использования. Также приходится копировать одинаковые куски кода для каждого элемента навигации.
Держитесь за кресло – в Angular существует разделение обязанностей и динамический HTML. А это значит, что наши данные живут в Модели, наш HTML живёт в виде маленького шаблона, который будет преобразован в Вид, а Контроллер мы используем для соединения двух этих понятий, обеспечивая поддержку изменений Модели и Вида. То есть, навигация может выводиться динамически, создаваясь из одного элемента списка, и автоматически повторяться для каждого пункта из Модели. Это упрощённая концепция, позже мы ещё поговорим о шаблонах.
Разница между MVC и MVVM в том, что MVVM специально предназначен для разработки интерфейсов. Вид состоит из слоя презентации, ВидМодель содержит логику презентации, а Модель содержит бизнес-логику и данные. MVVM была разработана для облегчения двусторонней связи данных, на чём и процветают фреймворки типа AngularJS. Мы сосредоточимся на пути MVVM, так как в последние годы Angular склоняется именно туда.
2.2 Двусторонняя связь данных
Двусторонняя связь данных – очень простая концепция, предоставляющая синхронизацию между слоями Модели и Вида. Изменения Модели передаются в Вид, а изменения Вида автоматически отражаются в Модели. Таким образом, Модель становится актуальным источником данных о состоянии приложения.
Angular использует простые Объекты JavaScript для синхронизации Модели и Вида, в результате чего обновлять любой из них легко и приятно. Angular преобразовывает данные в JSON и лучше всего общается методом REST. При помощи такого подхода проще строить фронтенд-приложения, потому что всё состояние приложения хранится в браузере, а не передаётся с сервера по кусочкам, и нет опасения, что состояние будет испорчено или потеряно.
Связываем мы эти значения через выражения Angular, которые доступны в виде управляющих шаблонов. Также мы можем связывать Модели через атрибут под названием ng-model. Angular использует свои атрибуты для разных API, которые обращаются к ядру Angular.
2.3 Инъекция зависимостей (Dependency Injection, DI)
DI – шаблон разработки программ, который определяет, как компоненты связываются со своими зависимостями. Инъекция — это передача зависимости к зависимому Объекту, и эти зависимости часто называют Сервисами.
В AngularJS мы хитрым образом используем аргументы функции для объявления нужных зависимостей, а Angular передаёт их нам. Если мы забудем передать зависимость, но сошлёмся на неё там, где она нужна нам, Сервис будет не определен и в результате произойдёт ошибка компиляции внутри Angular. Но не волнуйтесь, angular выбрасывает свои ошибки и они очень просты в отладке.
2.4 Приложения на одну страницу (Single Page Application, SPA), управление состоянием и Ajax (HTTP)
В приложении на одну страницу (SPA) либо весь необходимый код (HTML, CSS and JavaScript) вызывается за одну загрузку страницы, либо нужные ресурсы подключаются динамически и добавляются к странице по необходимости, обычно в ответ на действия пользователя. Страница не перезагружается во время работы, не передаёт управление другой странице, хотя современные технологии из HTML5 позволяют одному приложению работать на нескольких логических страницах. Взаимодействие с SPA часто происходит при помощи фонового общения с сервером.
В более старых приложениях, когда состояние программы хранилось на сервере, случались различия между тем, что видит пользователь и тем, что хранилось на сервере. Также ощущалась нехватка состояния приложения в модели, так как все данные хранились в шаблонах HTML и динамичными не являлись. Сервер подготавливал статичный темплейт, пользователь вводил туда информацию и браузер отправлял её обратно, после чего происходила перезагрузка страницы и бэкенд обновлял состояние. Любое несохранённое состояние терялось, и браузеру нужно было скачивать все данные после обновления страниц заново.
Времена изменились, браузер хранит состояние приложение, сложная логика и фреймворки приобрели популярность. AngularJS хранит состояние в браузере и передаёт изменения при необходимости через Ajax (HTTP) с использованием методом GET, POST, PUT и DELETE. Красота в том, что сервер может быть независим от фротенда, а фронтенд – от сервера. Те же самые сервера могут работать с мобильными приложениями с совершенно другим фронтендом. Это даёт нам гибкость, так как на бэкенде мы работаем с JSON-данными любым удобным нам способом на любом серверном ЯП.
2.5 Структура приложения
У Angular есть разные API, но структура приложения обычно одна и та же, поэтому почти все приложения строятся сходным образом и разработчики могут включаться в проект без усилий. Также это даёт предсказуемые API и процессы отладки, что уменьшает время разработки и быстрое прототипирование. Angular построен вокруг возможности тестирования («testability»), чтобы быть наиболее простым как в разработке, так и в тестировании.
3 Модули
Все приложения создаются через модули. Модуль может зависеть от других, или быть одиночным. Модули служат контейнерами для разных разделов приложения, таким образом делая код пригодным для повторного использования. Для создания модуля применяется глобальный Object, пространство имён фреймворка, и метод module.
3.1 Сеттеры (setters).
У приложения есть один модуль app.
Вторым аргументом идёт [] – обычно этот массив содержит зависимости модуля, которые нам нужно подключить. Модули могут зависеть от других модулей, которые в свою очередь тоже могут иметь зависимости. В нашем случае массив пустой.
3.2 Геттеры (Getters)
Для создания Controllers, Directives, Services и других возможностей нам надо сослаться на существующий модуль. В синтаксисе есть незаметное различие – мы не используем второй аргумент.
Модули могут храниться и вызываться и через переменную. Вот пример хранения модуля в переменной.
Теперь мы можем использовать переменную app для построения приложения.
3.4 HTML бутстрап
Если мы грузим файлы с JavaScript асинхронно, нам надо подгрузить приложение вручную через angular.bootstrap(document.documentElement, [‘app’]);.
$scope используется только внутри Контроллеров. Там мы привязываем данные Контроллера к Виду. Вот пример того, как мы объявляем данные в Контроллере:
Чтобы это отобразилось в DOM, мы должны присоединить Контроллер к HTML и сообщить Angular, куда вставлять значение.
Перед вами концепция области видимости Angular, подчиняющаяся некоторым правилам JavaScript в плане лексических областей видимости. Снаружи элемента, к которому присоединён Контроллер, данные находятся вне области видимости – так же, как переменная вышла бы за область видимости, если б мы сослались на неё снаружи её области видимости.
AngularJS 1.x – перевод курса от CodeSchool
Данная публикация является переводом оригинального курса CoodSchool с небольшими дополнениями, которые показались мне уместными в данном контексте. Публикация рассчитана на тех, кто только начинает знакомится с Angular.
Введение
AngularJS — популярная JavaScript библиотека, предназначенная, главным образом, для создания одностраничных веб-приложений с динамически обновляемым содержимым. Библиотека была написана словацким программистом Мишкой Хевери, который, работая в Google, получил от своего шефа задание выучить JavaScript. Он решил, что лучший способ изучить язык — это создать на его основе собственный фреймворк. Angular (звучит как «Ангула» и дословно переводится как «Угловатый») использует концепцию разделения данных и их представления, известную как MVC (M — model (данные), V — view (представление), С — controller (контролер, управляющая прослойка между ними обеспечивающая логику работы приложения).
Разные источники описывают назначение контролера либо так, что контролер реагирует только на действия пользователя и вносит изменения в модель, а потом эти изменения проявляются в интерфейсе без его участия. Либо так, что контролер не только вносит изменения в модель, но и отвечает за их получение от модели вместе с последующей обработкой по необходимости. Angular придерживается второго концепта.
Angular не зависит от внешних библиотек и написан на чистом JavaScript (об этом часто упоминается как о плюсе). При этом, как правило, его рекомендуют использовать в связке с Bootstrap CSS. Так же Angular не ограничивает совместное использование с JQuery, например, для визуальных эффектов. В принципе, и любые друге JS библиотеки, нацеленные на представление (дизайн), например, React от команды Facebook, могут использовать совместно с Angular без особого конфликта между собой.
1. Знакомимся с основными сущностями фреймворка: модуль, контролер, директива, выражение
Базовой структурой в Angular является модуль. По сути, это контейнер для взаимосвязанных функций. Поэтому создание приложения на Angular начинается с создания базового модуля, в котором мы указываем имя приложения. Прежде всего создадим файл app.js, который будет содержать следующий код:
AppName — имя нашего приложения. Оно, конечно, может быть любое другое на ваш вкус. В квадратных скобках [ ] указываются зависимости на другие модули, необходимые для работы нашего модуля. Если их нет, указываем просто пустой массив. Подробнее об этом позже.
Контролер [Controler]
Далее в модуле мы определяем контролер. Пока он один, но их может быть и много. Просто называем каждый следующий другим именем.
Теперь несколько важных действий внутри HTML кода (которые свяжут наш модуль с дизайном). Для этого создадим файл index.html, в котором прежде всего объявим, что мы используем модуль с выбранным нами именем
Теперь Angular знает, какой модуль использовать внутри данного HTML. Так же подключим саму библиотеку и файл с нашим приложением.
Выражение [Expression]
Внутри HTML в фигурных скобках <<>> указывается переменная. Эта переменная предварительно должна быть определена в контролере. Так же внутри <<>> мы можем указать не только переменную, но и выражение. Например: <<'Цена: '+store.data.price+'$'>>.
Обратите внимание, что выражения нельзя использовать внутри атрибута src тега IMG, поскольку браузер пытается загрузить изображение раньше, чем определен JS. Поэтому в Angular используется специальная директива ng-src:
Директива [Directive]
Директива специальный атрибут, который используется непосредственно внутри HTML тегов и обрабатывается Angular в соответствии с определенной для данной директивы логикой. Например, внутри блока, где нам нужно отображать данные, мы указываем имя контролера (в данном случае StoreController), который будет нам эти самые данные предоставлять. Делается это при помощи встроенной директивы ng-controller.
Другими часто используемыми встроенными директивами являются:
ng-show — если ее значение является False скрывает HTML элемент (используя display:none). Полезно когда нужно убрать элементы интерфейса в зависимости от состояния модели. Например для товара который продан автоматически убирать кнопку Купить.
ng-hide — обратный аналог ng-show. Т.е. скрывает элемент если его значение равно True.
ng-repeat — аналогичен по смыслу функции foreach. Т.е. циклично повторяет включенные в блок HTML теги. Например: добавим в контролер еще один продукт:
Теперь, для того чтобы вывести цены обоих продуктов, используем ng-repeat:
Angular имеет еще множество других встроенных директив, предназначенных для решения различных рутинных задач.
2. Фильтры, директивы и чистый код
Фильтры используются в выражениях и директивах и предназначены для изменения формата данных.
Теперь несколько слов о чистоте кода. Для этого используем следующий пример:
Как видно, логика находится непосредственно в HTML, что конечно не правильно и ее следует переместить на уровень контролера. Для этого добавим в функцию контролера следующий код:
Логика теперь находится внутри контролера и осталось только соответственно изменить HTML
3. Модели и Валидаторы на примере создания формы
Одной из основных особенностей Angular является так называемое двусторонние связывание (Two-way Data Binding), означающие, что изменение данных на странице (в форме) автоматически изменяет данные в модели (объекте хранящем данные), а изменение данных в модели так же автоматически обновляет связанную информацию на странице. На первый взгляд выглядит немного запутано, поэтому стоит пояснить на примере:
Так, например, изменение данных в селекторе автоматически отобразится на странице при помощи выражения <
Таким образом, данные с уровня представления (View) передаются на уровень хранения данных (Model) и обратно.
Так же нужно отметить, что при передачи данных модели с использовании директивы ng-model происходит валидация данных, установка специальных классов по итогам валидации и множество других полезных событий.
Теперь свяжем форму с контролером, который обеспечит её обработку. Для начала создадим сам контролер, содержащий метод addReview, который должен быть вызван при отправке формы.
После чего внесем необходимые коррективы в форму
Теперь добавим валидацию. Прежде всего отметим поля формы как обязательные при помощи аргумента required, а так же добавим условие, чтобы данные сохранялись только для валидной формы. Для этого в тег Form добавим опцию novalidate, которая выключит дефолтную HTML валидацию и добавим условие reviewForm.$valid, благодаря которому метод addReview будет вызываться только у валидной формы.
Все поля определенного типа, указанного при помощи атрибута type, будут проверятся на предмет корректного заполнения. При этом Angular будет добавлять к полю определенный CSS класс в зависимости от состояния валидации.
Так, например, для типа e-mail установленные классы будут меняться следующим образом:
Соответственно мы можем установить для данных классов любые подходящие нам CSS правила. Так, например, вокруг некорректно заполненного поля будет красная рамка, а вокруг корректно заполненного зеленая.
4. Создание собственных директив
Это позволяет писать выразительный код, который полностью передает структуру нашего приложения. И конечно, это позволяет сильно улучшить повторное использование кода.
В принципе, что касается повторного использования фрагментов HTML кода, Angular имеет в своем распоряжении директиву ng-include, которая позволяет вынести часть кода в отдельный файл. Выглядит это следующим образом:
Обратите внимание на одиночные кавычки вокруг имени. Они указывают Angular, что это строка с именем, а не переменная, содержащая имя файла.
Соответственно в файле product-title.html будет находится код, который Angular вставит как содержимое тега H3. Например:
Как видно, вставляемый таким образом код может содержать выражения, которые будут обработаны после вставки такого фрагмента в общий код.
Но вернемся обратно к созданию собственных директив. Делается это следующим образом:
Теперь в мы можем использовать это как HTML тег. Обратите внимание, что имя директивы productTitle в HTML трансформируется в product-title.
Другой способ кастомизации тега является создание собственного атрибута. В этом случае, вместо E(Element) при создании директивы нам нужно указать A(Attribute) для свойства restrict. После этого HTML тег будет выглядеть следующим образом:
Рекомендуется использовать «restrict: E» для вставки виджетов и других полностью самостоятельных элементов, содержащих собственную логику, а «restrict: А» — для примесей (mix-in).
В случае, когда речь идет о виджете, нам не обойтись без контролера, который будет содержать всю необходимую логику. Ангулар позволяет реализовать это несколькими способами. Прежде всего можно просто добавить атрибут ng-controller:
Но более правильно будет использовать свойство controller внутри функции, создающей нашу директиву:
5. Зависимости и Сервисы (Dependencies and Services )
Зависимости, это модули которые необходимы для обеспечения функциональности создаваемого нами нового модуля. Их так же можно рассматривать как способ улучшить структуру приложения, распределив самостоятельные части логики между различными модулями. Рассмотрим следующий пример:
Логично было бы вынести директивы в самостоятельный модуль или даже для каждой создать свой собственный модуль, в зависимости от необходимой гибкости.
Но в данном случае, чтобы избыточно не усложнять структуру приложения, вынесем их общий модуль.
Теперь укажем модуль store-products как зависимость для модуля store:
Последним шагом нужно не забыть подключить наш новый файл:
В итоге мы разделили модули на основе функциональности.
app.js — содержит топ-левел модуль подключаемый при помощи директивы ng-app;
products.js — содержит всю функциональность для продуктов и только продуктов.
В качестве примера наиболее популярных сервисов можно привести следующие:
$http — коммуникация со сервером посредством XMLHttpRequest;
$log — логирование сообщений в консоль браузера;
$filter — фильтрация данных в массиве;
… полный список.
Пример включения зависимостей (dependency injection) в контролер.
Введение в Angular
Что такое Angular. Первый проект
Angular представляет фреймворк от компании Google для создания клиентских приложений. Прежде всего он нацелен на разработку SPA-решений (Single Page Application), то есть одностраничных приложений. В этом плане Angular является наследником другого фреймворка AngularJS. В то же время Angular это не новая версия AngularJS, а принципиально новый фреймворк.
Angular предоставляет такую функциональность, как двустороннее связывание, позволяющее динамически изменять данные в одном месте интерфейса при изменении данных модели в другом, шаблоны, маршрутизация и так далее.
Одной из ключевых особенностей Angular является то, что он использует в качестве языка программирования TypeScript. Поэтому перед началом работы рекомендуется ознакомиться с основами данного языка, про которые можно прочитать здесь.
Но мы не ограничены языком TypeScript. При желании можем писать приложения на Angular с помощью таких языков как Dart или JavaScript. Однако TypeScript все таки является основным языком для Angular.
Начало работы c Angular
Следует учитывать, что Angluar 13 поддерживает те версии node.js, которые в текущий момент находятся в статусе «Active LTS» или «Maintenance LTS». На момент написания данной статьи это версии от 14 и 16. Проверить статус определенной версии node.js можно по адресу: https://nodejs.org/en/about/releases/. Поэтому, если Node.js уже ранее был установлен, но имеет более старую или, наоборот новую, но еще не поддерживаемую версию, то лучше его обновить.
То же самое касается и npm. Если версия слишком старая или, наоборот, одна из последних, то Angular может ее не поддерживать. При работе с Angular лучше полагаться на ту версию npm, которая устанавливается вместе с LTS-версией Node.js.
Установка Angular CLI
Для компиляции приложения мы будем использовать инфрастуктуру Angular CLI. Angular CLI упрощает создание приложения, его компиляцию. Angular CLI распространяется как пакет npm, поэтому для его использования его необходимо сначала установить. Для установки Angular CLI откроем консоль/командную строку и выполним в ней следующую команду:
Данная команда установит пакет @angular/cli в качестве глобального модуля, поэтому в последующем при создании новый проектов Angular его не потребуется устанавливать заново.
Ту же команду можно использовать для обновления Angluar CLI при выходе новой версии фреймворка. Проверить версию CLI можно в командной строке/консоли с помощью команды:
Установка пакетов. Package.json
В папке проекта создадим новый файл package.json со следующим содержимым:
Данный файл устанавливает пакеты и зависимости, которые будут использоваться проектом. В секции dependencies в основном определяются пакеты angular, которые необходимы приложению для работы. В секции devDependencies прописаны только те пакеты, которые будут использоваться для разработки. В частности, это пакеты для работы с языком typescript (так как мы будем писать код приложения на языке TypeScript), а также пакеты, необходимые для компиляции приложения с помощью инфраструктуры Angular CLI.
В секции «scripts» описаны используемые команды. В частности, команда ng serve запускает простенький веб-сервер для тестирования приложения и само приложение. А команда ng build компилирует приложение.
Затем откроем командную строку (терминал) и перейдем в ней к папке проекта с помощью команды cd:
Определение приложения
Создание компонента Angular
Компоненты представляют основные строительные блоки приложения Angular. Каждое приложение Angular имеет как минимум один компонент. Поэтому создадим в папке src/app новый файл, который назовем app.component.ts и в котором определим следующий код компонента:
Создание модуля приложения
Приложение Angular состоит из модулей. Модульная структура позволяет легко подгружать и задействовать только те модули, которые непосредственно необходимы. И каждое приложение имеет как минимум один корневой модуль. Поэтому создадим в папке src/app новый файл, который назовем app.module.ts со следующим содержимым:
Этот модуль, который в данном случае называется AppModule, будет входной точкой в приложение.
С помощью директив import здесь импортируется ряд нужных нам модулей. Прежде всего, это модуль NgModule. Для работы с браузером также требуется модуль BrowserModule. Так как наш компонент использует элемент input или элемент формы, то также подключаем модуль FormsModule. И далее импортируется созданный ранее компонент.
Запуск приложения
Теперь нам надо указать Angular, как запускать наше приложение. Для этого создадим в папке src (на уровень выше, чем расположены файлы app.component.ts и app.module.ts) файл main.ts со следующим содержимым:
Этот код инициализирует платформу, которая запускает приложение, и затем использует эту платформу для загрузки модуля AppModule.
Также в папке src определим еще один файл, который назовем polyfills.ts со следующим кодом:
Создание главной страницы
Далее определим в папке src главную страницу index.html приложения:
Определение конфигурации
Поскольку для определения кода приложения применяется язык TypeScript, поэтому также создадим в корневой папке проекта новый файл tsconfig.json :
Angular.json
Для компиляции приложения мы будем использовать Angular CLI, поэтому нам надо описать поведение CLI с помощью файла angular.json. Итак, добавим в корневую папку проекта новый файл angular.json и определим в нем следующее содержимое:
Проект определяет следующие опции:
projectType : тип проекта. Значение «application» указывает, что проект будет представлять приложение, которое можно будет запускать в браузере
root : указывает на папку файлов проекта относительно рабочей среды. Пустое значение соответствует корневой папке проекта, так как в данном случае рабочая среда и каталог проекта совпадают
sourceRoot : определяет корневую папку файлов с исходным кодом. В нашем случае это папка src, где собственно определены все файлы приложения
Параметр options задает параметры построения файлов. Для команды «build» здесь определены следующие опции:
outputPath : путь, по которому будет публиковаться скомпилированное приложение
index : путь к главной странице приложения
main : путь к главному файлу приложения, где собственно запускается приложение Angular
polyfills : путь к файлу полифилов
tsConfig : путь к файлу конфигурации TypeScript
aot : указывает, будет ли использоваться компиляция AOT (Ahead-Of-Time) (предварительная компиляция перед выполнением). В данном случае значение true означает, что она используется
Последняя опция defaultProject указывает на проект по умолчанию. В данном случае это наш единственный проект.
Если мы используем TypeScript для работы с Angular и Angular CLI для компиляции, то эти файлы package.json, tsconfig.json и angular.json фактически будут присутствовать в каждом проекте. И их можно переносить из проекта в проект с минимальными изменениями. Например, в файле angular.json вместо названия проекта «helloapp» будет соответствующее название проекта. В файле package.json можно будет задать какие-то другие версии пакетов, если предыдущие версии устарели. Можно будет изменить название проекта, версию. Можно подправить настройки TypeScript или Angular CLI, но в целом общая организация будет той же.
В итоге у нас получится следующая структура проекта:
Запуск проекта
И теперь, когда все готово, мы можем запустить проект. Для этого в командной строке (терминале) перейдем к папке проекта с помощью команды cd и затем выполним команду ng serve :
Введем в текстовое поле какое-нибудь имя, и оно тут же отобразится в заголовке.
Важно отметить, что пока приложение запущено, мы можем поменять код, и Angular CLI почти моментально перекомпилирует и перезапустит приложение.
Стоит отметить, что консоль может быть скрыта после запуска приложения, но тем не менее оно будет запущено, и мы сможем к нему обращаться. А при изменениях произойдет его перекомпиляция.