Что такое angular?
Содержание:
- Популярные встроенные Angular-директивы [ править | править код ]
- Google ненавидит SPA
- Иерархическое внедрение зависимостей
- Как устроен Angular: компоненты
- Философия Angular [ править | править код ]
- AngularJS Applications
- Действия (actions), редукторы (reducer), селекторы (select), хранилище (store) и побочные эффекты (effects) NGRX
- Пример NGRX
- Управление состоянием в Angular приложениях, @ngrx/store
- … и недостатки
- Работа с pipes
- Единый источник правды
- Что такое AngularJS
- Что было до Angular и других SPA-фреймворков
- Когда использовать NGRX
- Написание бесполезных селекторов директив
- Отлично … так каковы же преимущества использования NGRX
Популярные встроенные Angular-директивы [ править | править код ]
С помощью директив AngularJS можно создавать пользовательские HTML-теги и атрибуты, чтобы добавить поведение некоторым элементам.
ng-app Объявляет элемент корневым для приложения. ng-bind Автоматически заменяет текст HTML-элемента на значение переданного выражения. ng-model То же, что и ng-bind, только обеспечивает двустороннее связывание данных. Изменится содержимое элемента — ангуляр изменит и значение модели. Изменится значение модели — ангуляр изменит текст внутри элемента. ng-class Определяет классы для динамической загрузки. ng-controller Определяет JavaScript-контроллер для вычисления HTML-выражений в соответствии с MVC. ng-repeat Создает экземпляр DOM для каждого элемента из коллекции. ng-show и ng-hide Показывает или скрывает элемент, в зависимости от значения логического выражения. ng-switch Создаёт экземпляр шаблона из множества вариантов, в зависимости от значения выражения. ng-view Базовая директива, отвечает за обработку маршрутов , которые принимают JSON перед отображением шаблонов, управляемых указанными контроллерами. ng-if Удаляет или создаёт часть DOM-дерева в зависимости от значения выражения. Если значение выражения, назначенного ngIf, равно false, элемент удаляется из DOM, иначе — вновь клонированный элемент вставляется в DOM.
Также существует возможность создавать настраиваемые директивы, используя в том числе шаблоны в теге script.
Google ненавидит SPA
Когда мы говорим про современные интернет магазины, мы представляем себе тяжелые для понимания серверы, рендрящие тысячи статических страничек. Причем именно эти тысячи отрендеренных страниц одна из причин, почему Single Page Applications не прижились в электронной коммерции. Даже крупнейшие магазины электронной коммерции по-прежнему выглядят как куча статических страниц. Для пользователя это нескончаемый цикл кликов, ожиданий и перезагрузки страниц.
Одностраничные приложения приятно отличаются динамичностью взаимодействия с пользователем и более сложным UX. Но как не прискорбно обычно пользовательский комфорт приносится в жертву SEO оптимизации. Для сеошника сайт на angular – это своего рода проблема, поскольку поисковикам трудно индексировать страницы с динамическим контентом.
Мы любим JS и Angular. Мы верим, что классный и удобный UX может быть построен на этом стеке технологий, и мы можем решить все сопутствующие проблемы. В какой-то момент мы столкнулись с . Это модуль для рендеринга на стороне сервера. Сначала нам показалось, вот оно – решение! Но радость была преждевременной — и отсутствие больших проектов с его применением тому доказательство.
Иерархическое внедрение зависимостей
Я уже упоминал, что Angular2-приложение — это дерево компонентов. И у каждого компонента есть свой роутер и инжектор. Таким образом дерево инжекторов и компонентов параллельны.
Какие плюсы даёт такой подход? Например, теперь легко можно настроить один и тот же сервис по-разному, в зависимости от компонента, в который он внедряется. При этом, можно не бояться как-то повлиять на другие компоненты выше или на том же уровне иерархии, так как они будут использовать другие экземпляры того же сервиса. Компонент теперь не зависит от того, как был сконфигурирован какой-то сервис. Если компоненту нужен отдельный экземпляр сервиса, он просто добавляет его в секцию .
Заметьте, в коде сервисов нет нигде упоминания о провайдерах. Мы не можем зарегистрировать какой-то провайдер в рамках какого-нибудь сервиса. Если в сервис внедряется другой сервис, его провайдер регистрируется в каком-то компоненте. Мы не сможем внедрить сервис без компонента. Таким образом, ещё раз подчёркивается компонентный подход всего фреймворка: сервисный слой стал вторичным, на первое место вышли компоненты. И у каждого компонента могут быть свои личные изолированные от других экземпляры сервисов.
Разумеется, ангуляр не создаёт для каждого компонента отдельный инжектор. Это было бы довольно неэффективно. Но в любом случае, каждый компонент имеет свой инжектор, даже если делит его с другим компонентом.
Как происходит выбор нужного экземпляра зависимости? У каждого компонента зависимость либо прописана в секции , либо должна быть найдена выше по иерархии. Для инжектора корневого компонента выше по иерархии стоит только глобальный инжектор, который создаётся при вызове функции .
Если поле не пустое, инжектор компонента становится равным результату выполнения статического метода , который резолвит переданный массив провайдеров и создаёт новый экземпляр инжектора. У каждого инжектора есть поле , которое содержит ссылку на родительский инжектор. Если компоненту требуется зависимость, инжектор компонента пытается найти нужную у себя. Если не находит, пытается найти в родительских инжекторах вплоть до корневого.
Вот пример того, как работают инжекторы с иерархией:
Тут 2 сервиса и 2 компонента. В родительском компоненте регистрируются 2 сервиса ( и ), в дочернем — только . Если понажимать на кнопки , то одинаковые массивы будут только у , так как дочерний компонент, не найдя у себя зависимость использует инстанс, полученный из родительского компонента. А вот экземпляр у дочернего компонента создастся новый. Поэтому дочерний компонент будет писать в свой экземпляр, а родительский — в свой.
Означает ли это, что сервисы в Angular2 не являются синглтонами? В конкретном инжекторе не может быть больше 1-го инстанса сервиса. Но так как самих инжекторов может быть несколько, то и разных инстансов одного и того же сервиса во всём приложении может быть больше одного.
Как устроен Angular: компоненты
Angular-приложения состоят из независимых элементов. Эти элементы называются компонентами, и у каждого компонента своё поведение.
Например, лента новостей — один компонент. Отвечает за отображение списка новостей на странице. Кнопка «Прочитать» — другой компонент. Отвечает за переход со страницы списка новостей к выбранной новости.
Обычно компонент программируют так, чтобы он отображал элемент на экране и выполнял какое-то действие. Компонент может реагировать на клик, сворачиваться, разворачиваться, скрываться, перебрасывать на другую страницу и так далее.
Компоненты подчиняются жизненным циклам — меняются и работают по нескольким запрограммированным сценариям. Возьмём ситуацию, когда мы переходим со страницы списка новостей к одной новости. В этом случае компонент «Лента новостей» уничтожается и при необходимости создаётся повторно. Жизненные циклы разгружают память и ускоряют приложение.
Страница с шапкой, лентой новостей и тремя кнопками. Каждый элемент — независимый компонент, который выполняет какое-то действие внутри приложения
Философия Angular [ править | править код ]
AngularJS спроектирован с убеждением, что декларативное программирование лучше всего подходит для построения пользовательских интерфейсов и описания программных компонентов , в то время как императивное программирование отлично подходит для описания бизнес-логики . Фреймворк адаптирует и расширяет традиционный HTML, чтобы обеспечить двустороннюю привязку данных для динамического контента, что позволяет автоматически синхронизировать модель и представление. В результате AngularJS уменьшает роль DOM-манипуляций и улучшает тестируемость.
Цели разработки
Отделение DOM-манипуляции от логики приложения, что улучшает тестируемость кода.
Отношение к тестированию как к важной части разработки. Сложность тестирования напрямую зависит от структурированности кода
Разделение клиентской и серверной стороны, что позволяет вести разработку параллельно.
Проведение разработчика через весь путь создания приложения: от проектирования пользовательского интерфейса, через написание бизнес-логики, к тестированию.
Angular придерживается MVC-шаблона проектирования и поощряет слабую связь между представлением, данными и логикой компонентов. Используя внедрение зависимости, Angular переносит на клиентскую сторону такие классические серверные службы, как видозависимые контроллеры. Следовательно, уменьшается нагрузка на сервер и веб-приложение становится легче.
AngularJS Applications
AngularJS modules define AngularJS applications.
AngularJS controllers control AngularJS applications.
The ng-app
directive defines the application, the ng-controller
directive defines the controller.
AngularJS Example
<div ng-app=»myApp» ng-controller=»myCtrl»>First Name: <input type=»text» ng-model=»firstName»><br>
Last Name: <input type=»text» ng-model=»lastName»><br><br>
Full Name: {{firstName + » » + lastName}}</div><script>
var app = angular.module(‘myApp’, []);app.controller(‘myCtrl’,
function($scope) { $scope.firstName= «John»; $scope.lastName= «Doe»;});</script>
AngularJS modules define applications:
var app = angular.module(‘myApp’, []);
AngularJS controllers control applications:
AngularJS Controller
app.controller(‘myCtrl’,
function($scope) { $scope.firstName= «John»;
$scope.lastName= «Doe»;});
You will learn more about modules and controllers later in this tutorial.
❮ Previous
Next ❯
Действия (actions), редукторы (reducer), селекторы (select), хранилище (store) и побочные эффекты (effects) NGRX
Это основные строительные единицы жизненного цикла . Каждый из них берет на себя часть процесса от запуска операции до изменения нашего состояния и извлечения данных.
На этой картинке мы видим жизненный цикл ngrx. Давайте разберём его …
1. В наиболее распространенном сценарии все начинается в представлении компонента (). Взаимодействие с пользователем может привести к тому, что компонент отправит действие ().
2.1. Если действие не вызывает эффект (), то редуктор отфильтрует действие (обычно с помощью оператора switch), и вернёт новое состояние, которое будет результатом слияния старого состояния со значением, которое изменилось после вызова действия.
2.2. Если действие вызвало эффект, то это говорит о необходимости обработки побочных эффектов перед вызовом редуктора. Это может быть что-то вроде вызова службы HTTP для получения данных.
2.2.1. После того, как эффект отработал (побочные эффекты закончились), он запускает новое действие «состояние-результат» (побочные эффекты могут быть успешными или неудачными), и мы возвращаемся к пункту 2.1.
3. Теперь у хранилища есть новое состояние. Состояние может быть большим деревом — объектом, поэтому вводит селекторы, чтобы иметь возможность использовать только необходимые фрагменты объекта.
Пример NGRX
- Установка библиотеки
- Создание структуры папок для хранилища
- Создание хранилища и начальных значений
- Создание действий (Actions)
- Создание редукторов (Reducers)
- Создание эффектов (Effects)
- Создание селекторов (Selectors)
- Конечная настройка
- Использование хранилища в компонентах
Создание хранилища и начальных значений
- Мы создаем и экспортируем интерфейс со структурой пользовательской среды.
- Мы делаем то же самое с начальным пользовательским состоянием, которое реализует недавно созданный интерфейс.
- Состояние приложения содержит состояние пользователя и конфигурации, а также состояние маршрутизатора.
- Потом задаем начальное состояние приложения.
- Наконец, экспортирует функцию, чтобы получить начальное состояние (мы будем использовать его позже).
Создание Действий
- Мы экспортируем Enum, содержащий определение для типов действий. Таким образом, мы избегаем использования и повторения строк для использования типов действий, процесс, который может легко порождаться ошибками.
- Потом мы создаем и экспортируем класс для каждого из ваших действий. Все они должны реализовать интерфейс Action из ngrx. Наконец, мы устанавливаем тип в одно из значений перечислений, и если вам нужно полезное содержимое для действия, вы добавляете его в конструктор класса.
- Наконец, мы экспортируем тип, содержащий наши классы действий. Это обеспечит нам проверку типов, которую мы можем использовать, например, в наших редукторах.
Создание Редукторов
- Объявление редуктора получает состояние и, в этом случае, действия пользователя и возвращает IUserState.
- Используя оператор switch, мы генерируем наблюдения для каждого возможного типа действия.
- Каждый случай возвращает новый объект, который является результатом слияния старого состояния и нового значения.
- Все редукторы имеют результат по умолчанию, который просто возвращает состояние без каких-либо изменений.
Добавим Эффекты
- Мы объявляем наши пользовательские эффекты с помощью инъекционного декоратора.
- Мы объявляем наши эффекты, используя декоратор эффектов, предоставленный ngrx/Effects.
- Используя действия, предоставленные ngrx / Effects, мы собираемся запустить конвейер нашего оператора для этого эффекта.
- Следующим шагом является установка типа действия эффекта с помощью оператора ofType.
- Следующие части представляют собой операторы rxjs, которые мы используем для получения того, что нам нужно (у нас уже есть ссылка на документацию по rxjs в этой статье).
- Наконец, в последнем операторе Effect отправит еще одно действие.
- В конструкторе мы внедряем сервисы, которые мы собираемся использовать, действия для ngrx / Effects, и в этом случае также хранилище (учтите, что это демо, и мы получаем выбранного пользователя из списка пользователей в наше хранилище).
Итоговая настройка
- Мы импортируем наши редукторы и предоставляем их в forRoot модуля хранилища.
- Мы импортируем наши эффекты и предоставляем их внутри массива в модуль forRoot эффектов.
- Мы устанавливаем конфигурацию для модуля состояния маршрутизатора, предоставляющего маршрутизатор stateKey.
- И мы добавляем инструменты разработчика магазина, если среда не является производственной.
Использование хранилища в некоторых компонентах
Во-первых, давайте получим конфигурацию при запуске приложения:
- Мы добавляем хранилище в наш app.component.
- Мы устанавливаем для свойства компонента значение селектора в конфигурации, потому что хотим отобразить часть этой информации в HTML.
- В onInit мы отправляем действие, чтобы получить конфигурацию.
- Подобно тому, как мы управляем конфигурацией, мы собираемся получить список пользователей. Сначала мы внедряем хранилище в компонент пользователя.
- На onInit мы отправляем действие, чтобы получить пользователей.
- Мы создаем свойство для компонента и присваиваем ему список пользователей, используя селектор списка пользователей.
Давайте посмотрим на компонент пользовательского контейнера:
Управление состоянием в Angular приложениях, @ngrx/store
Довольно часто при разработке сложных приложений мы сталкиваемся с необходимостью хранить состояние и реагировать на его изменения. Для приложений, разрабатываемых на фреймворке ReactJs существует множество библиотек, позволяющих управлять состоянием приложения и реагировать на его изменения — Flux, Redux, Redux-saga и т.д. Для Angular приложений существует контейнер состояний на основе RxJS вдохновленный Redux — @ngrx/store. Правильное управление состоянием приложения избавит разработчика от множества проблем при дальнейшем расширении приложения.
Почему Redux?
Redux позиционирует себя как предсказуемый контейнер состояния (state) для JavaScript приложений. Redux вдохновлен Flux и Elm.
Redux предлагает думать о приложении, как о начальном состоянии модифицируемом последовательностью действий (actions), что может являться хорошим подходом при построении сложных веб-приложений.
Redux не связан с каким-то определенным фреймворком, и хотя разрабатывался для React, может использоваться с Angular или jQuery.
Основные постулаты Redux:
- одно хранилище для всего состояния приложения
- состояние доступно только для чтения
- изменения делаются «чистыми» функциями, к которым предъявляются следующие требования:
- не должны делать внешних вызовов по сети или базе данных;
- возвращают значение, зависящее только от переданных параметров;
- аргументы являются неизменяемыми, т.е. функции не должны их изменять;
- вызов чистой функции с теми же аргументами всегда возвращает одинаковый результат;
Пример функции управления состоянием:
В основном модуле приложения импортируется Reducer и с использованием функции делаем его доступным для Angular инжектора:
Далее производится внедрение сервиса в необходимые компоненты и сервисы. Для выбора «среза» состояния используется функция store.select():
@ngrx/router-store
В некоторых случаях удобно связывать состояние приложения с текущим маршрутом приложения. Для этих случаев существует модуль @ngrx/router-store. Чтобы приложение использовало для сохранения состояния, достаточно подключить и добавить вызов в основном модуле приложения:
Теперь добавляем в основное состояние приложения:
Дополнительно можем указать начальное состояние приложения при объявлении store:
Поддерживаемые действия:
UPD: В комментария подсказали, что данные действий не будут доступны в новой версии @ngrx, для новой версии
Использование контейнера состояния избавит от многих проблем при разработке сложных приложений
Однако, важно делать управление состоянием как можно проще. Довольно часто приходится сталкиваться с приложениями, в которых присутствует излишняя вложенность состояний, что лишь усложняет понимание работы приложения
… и недостатки
- У , конечно, есть кривая обучения. Не большая, но и не такая маленькая, и я думаю, что это требует некоторого опыта или глубокого понимания некоторых программных шаблонов. Это не является проблемой для любого разработчик среднего уровня, но младший может поначалу немного запутаться.
- Для меня это ощущается немного многословно (прим пер.: речь о проблеме множества заготовок кода — ). Поэтому каждый раз, когда вы добавляете какое-либо свойство в состояние (), вам нужно добавлять действия () и диспетчеры (). Вам может потребоваться обновить или добавить селекторы (), эффекты (), если таковые имеются, и обновить хранилище (). Кроме того, вы будете собирать конвейер () операторов и наблюдаемых потоков () везде где это потребуется.
- не является частью библиотек , и не поддерживается Google. По крайней мере, не напрямую, потому что среди контрибьюторов есть разработчики из команды . Это ещё один пункт для обдумывания — вы добавляете в зависимости тяжёлую библиотеку.
Работа с pipes
Последнее обновление: 16.05.2021
Pipes представляют специальные инструменты, которые позволяют форматировать отображаемые значения. Например, нам надо вывести определенную дату:
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<div>Без форматирования: `myDate`</div> <div>С форматированием: {{myDate | date}}</div>` }) export class AppComponent { myDate = new Date(1961, 3, 12); }
Здесь создается дата, которая дважды выводится в шаблоне. Во втором случае к дате применяется форматирование с помощью класса DatePipe.
Встроенные pipes
В Angular есть ряд встроенных pipes. Основные из них:
-
CurrencyPipe: форматирует валюту
-
PercentPipe: форматирует проценты
-
UpperCasePipe: переводит строку в верхний регистр
-
LowerCasePipe: переводит строку в нижний регистр
-
DatePipe: форматирует дату
-
DecimalPipe: задает формат числа
-
SlicePipe: обрезает строку
При применении классов суффикс отбрасывается (за исключением DecimalPipe — для его применения используется название «number»):
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<div>{{welcome | uppercase}}</div> <div>{{welcome | lowercase}}</div> <div>{{persentage | percent}}</div> <div>{{persentage | currency}}</div>` }) export class AppComponent { welcome: string = "Hello World!"; persentage: number = 0.14; }
Параметры в pipes
Pipes могут получать параметры. Например, пайп SlicePipe, который обрезает строку, может получать в качестве параметра, начальный и конечный индексы подстроки,
которую надо вырезать:
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<div>{{welcome | slice:3}}</div> <div>{{welcome | slice:6:11}}</div>` }) export class AppComponent { welcome: string = "Hello World!"; }
Все параметры в пайп передаются через двоеточие. В данном случае вырезает подстроку, начиная с 6 до 11 индекса. При этом,
если начала выреза строки обязательно передавать, то конечный индекс необязателен. В этом случае в качестве конечного индекса выступает конец строки.
Форматирование дат
DatePipe в качестве параметра может принимать шаблон даты:
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<div>{{myDate | date:"dd/MM/yyyy"}}</div>` }) export class AppComponent { myDate = Date.now(); }
Форматирование чисел
DecimalPipe в качестве параметра принимает формат числа в виде шаблона:
{{ value | number ] }}
-
: само выводимое значение
-
: строка в формате «minIntegerDigits.minFractionDigits-maxFractionDigits», где
-
— минимальное количество цифр в целой части
-
— минимальное количество цифр в дробной части
-
— максимальное количество цифр в дробной части
-
-
: код применяемой культуры
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<div>{{pi | number:'2.1-2'}}</div> <div>{{pi | number:'3.5-5'}}</div>` }) export class AppComponent { pi: number = 3.1415; }
Форматирование валюты
CurrencyPipe может принимать ряд параметров:
{{ value | currency ] ] ] }}
-
: выводимая сумма
-
: код валюты согласно спецификации ISO 4217. Если не указан, то по умолчанию применяется USD
-
: указывает, как отображать символ валюты. Может принимать следующие значения:
-
: отображает код валюты (например, USD)
-
(значение по умолчанию): отображает символ валюты (например, $)
-
: некоторые страны используют в качестве символа валюты несколько символов, например, канадский доллар — CA$, данный параметр
позволяет получить собственно символ валюты — $ -
: отображает произвольную строку
-
-
: формат числа, который применяется в DecimalPipe
-
: код используемой локали
Цепочки pipes
Вполне возможно, что мы захотим применить сразу несколько pipes к одному значению, тогда мы можем составлять цепочки выражений, разделенные вертикальной чертой:
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<div>{{message | slice:6:11 | uppercase}}</div>` }) export class AppComponent { message = "Hello World!"; }
НазадВперед
Единый источник правды
Для архитектуры redux и ngrx это означает, что состояние всего вашего приложения хранится в древовидном объекте, — в одном хранилище.
Преимущества наличия единственного источника правды более чем достаточны, но поскольку он будет влиять на любое приложение , для меня более интересно следующее:
Когда вы создаете приложение angular, вы обычно разделяете состояние, и обрабатываете их в разных сервисах. По мере того как ваше приложение растёт, отслеживание изменения состояний становится беспорядочным, их трудно отлаживать и поддерживать. Наличие единственного источника правды решает эту проблему, поскольку состояние обрабатывается только в одном объекте и в одном месте, поэтому отладка или добавление изменений становится намного проще.
Что такое AngularJS
Последнее обновление: 26.04.2017
AngularJS представляет собой opensource JavaScript-фреймворк, использующий шаблон MVC. Собственно использование MVC является его одной из отличительных особенностей.
Для описания интерфейса используется декларативное программирование, а бизнес-логика отделена от кода интерфейса, что позволяет улучшить тестируемость и
расширяемость приложений.
Другой отличительной чертой фреймворка является двустороннее связывание, позволяющее динамически изменять данные в одном месте интерфейса при
изменении данных модели в другом. Таким образом, AngularJS синхронизирует модель и представление.
Кроме того, AngularJS поддерживает такие функциональности, как Ajax, управление структорой DOM, анимация, шаблоны, маршрутизация и так далее. Мощь фреймворка,
наличие богатого функционала во многом повлияла на то, что он находит свое применение во все большем количестве веб-приложений, являясь на данный
момент наверное одним из самых популярных javascript-фреймворков.
На момент написания данного руководства последней версией фреймворка была версия 1.6.4.
Начало работы c AngularJS
При загрузке zip-пакета мы найдем в нем кроме самой библиотеки (angular.js) еще ряд дополнительных файлов и их минимизированные версии:
-
angular-touch.js: предоставляет поддержку событий сенсорного экрана
-
angular-animate.js: предоставляет функциональность анимации
-
angular-aria.js: предоставляет поддержку aria-атрибутов (accesible rich internet application)
-
angular-mocks.js: предоставляет mock-объекты для юнит-тестирования
-
angular-route.js: обеспечивает механизм маршрутизации
-
angular-sanitize.js: предоставляет функционал для управления потенциально опасным контентом (javascript, html)
-
angular-cookies.js: обеспечивает функционал для управления куками
-
angular-loader.js: используется для загрузки angularjs-скриптов
-
angular-messages.js: предоставляет функционал для вывода сообщений
-
angular-resource.js: обеспечивает функциональность для работы с ресурсами
-
Папка i18n: содержит js-файлы для разных локалей
Из всех загруженных скриптов в архиве нас будет интересовать прежде всего файл angular.min.js
Теперь собственно создадим приложение. Оно будет стандартным HelloWorld. Код html-страницы будет следующим:
<!doctype html> <html ng-app> <head> <meta charset="utf-8"> </head> <body> <label>Введите имя:</label> <input type="text" ng-model="name" placeholder="Введите имя"> <h1>Добро пожаловать `name`!</h1> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script> </body> </html>
Первое, наверное, что бросается в глаза — это новые атрибуты, добавленные к стандартным тегам html (в данном случае и
). Эти атрибуты являются директивами фреймворка AngularJS. Благодаря их встраиванию фреймворк позволяет добавить элементам определенное поведение.
Конкретно в данном случае директива объявляет элемент корневым для всего приложения, а
директива указывает модель «name», к которой будет привязано значение элемента input. И при изменении текста в элементе input, модель «name»
также будет динамически изменять свое значение.
Чуть ниже в элементе выводится значение этой модели.
И мы можем просто открыть данный файл в браузере и протестировать его работу.
Вперед
Что было до Angular и других SPA-фреймворков
Angular работает по принципу SPA, single-page application. Чтобы понять, что это такое, надо сначала понять, чем это не является.
Традиционный подход к веб-приложениям был примерно такой:
- Пользователь переходил на сайт.
- Браузер отправлял серверный запрос на поиск нужного адреса.
- Сервер находил страницу и передавал её на сайт.
- Пользователь смотрел на эту страницу и нажимал на какую-то ссылку.
- Браузер формировал повторный запрос, сервер собирал новую страницу и снова возвращал её на сайт. Цикл повторялся после каждого действия пользователя.
Это можно сравнить с заказом еды в ресторане, с той лишь разницей, что заказать можно только одно блюдо за один раз. Заказал салат, съел, только потом заказал горячее. Теперь сидишь ждёшь, пока тебе его принесут. Съел горячее — заказал чай. Ждёшь, пока вскипит чайник. Принесли чай — заказал десерт. Ждёшь, когда поднимутся коржи. Вот то же самое, только в тысячу раз быстрее.
Медленные сайты всех раздражали, и разработчики придумали SPA — сначала появилась технология, а затем Angular и другие инструменты для её реализации.
Когда использовать NGRX
Итак, по общему мнению, следует использовать в средних/крупных проектах, где управление состоянием становится трудным в обслуживании. Те кто фанатеют по шаблонам () скажут что-то вроде «если у вас есть состояние, у вас есть ».
Я согласен, что его следует использовать в средних или крупных проектах, когда у вас есть значительное количество состояний, и множество компонентов, использующих эти состояния. Но вы должны учитывать, что сам по себе предоставляет множество решений для управления состоянием. Если у вас есть сильная команда разработчиков, то, возможно, вам не нужно беспокоиться о .
При этом я считаю, что сильная команда разработчиков может решить использовать в проекте потому что они знают силу шаблона и операторов . И они чувствуют себя комфортно, работая и с тем, и с другим …
Написание бесполезных селекторов директив
Директивы Angular — мощный инструмент, позволяющий применять пользовательскую логику к различным элементам HTML. При этом также используются селекторы CSS, которые предоставляют еще больше возможностей. Для примера возьмем директиву , которая проверяет наличие ошибок в соответствующего элемента и применяет к нему определенный стиль. Допустим, мы добавляем в нее селектор атрибута . Она работает хорошо, однако теперь необходимо найти все элементы формы с атрибутом и добавить в них . Утомительная задача. Мы можем использовать селектор атрибута директивы . Директива выглядит следующим образом:
Теперь она будет автоматически связываться со всеми элементами управления формы в модуле.
Но на этом использование не заканчивается. Допустим, мы хотим применить анимацию тряски ко всем , в которых есть класс . Мы можем с легкостью написать директиву и привязать ее с помощью селектора класса: .
Используйте лучшие селекторы для директив, чтобы не загромождать HTML ненужными атрибутами.
Отлично … так каковы же преимущества использования NGRX
Мы уже упоминали большинство из них, когда говорили о принципах шаблона . Но давайте отметим наиболее важные преимущества использования шаблона в приложении (на взгляд автора):
- Поскольку у нас есть один источник правды, и вы не можете напрямую изменить состояние, приложения будут работать более согласованно.
- Использование шаблона дает нам много интересных функций (), облегчающих отладку.
- Тестирование приложений становится проще, поскольку мы вводим чистые функции для обработки изменений состояния, а также потому, что и , и , имеют множество замечательных возможностей для тестирования.
- Как только вы почувствуете себя комфортно при использовании , понимание потока данных в ваших приложениях станет невероятно простым и предсказуемым.