Angular
Содержание:
- Изменения делаются чистыми функциями
- AngularJS Extends HTML
- Что делает Angular?
- Настроить всё вместе
- AngularJS Directives
- Пример использования NGRX
- Что такое AngularJS
- Когда использовать Angular?
- Как выглядит Angular-приложение?
- Создание компонента Angular¶
- Структурные директивы ngIf, ngFor, ngSwitch
- AngularJS Expressions
- Построение проекта
- Angular.json¶
- Действия (actions), редукторы (reducer), селекторы (select), хранилище (store) и побочные эффекты (effects) NGRX
- Какую версию Angular мне лучше использовать?
- Структура папок хранилища
- … и недостатки
- Создание эффектов
Изменения делаются чистыми функциями
Операция, инициируемая отправкой действия, будет чистой функцией, называемой в архитектуре — (редукторами).
Эти редукторы (просто чистые функции) получают действие () и состояние (), в зависимости от отправленного действия (обычно отфильтрованного оператором ), они выполняют операцию и возвращают новый объект состояния.
Преимущества использования чистых функций хорошо известны, например то что они сразу готовы к тестированию. Если вы передадите те же аргументы, то получите тот же результат.
Этот подход также позволяет нам перемещаться между различными экземплярами нашего состояния с помощью инструментов разработки и видеть, что изменилось между экземплярами, кто их изменил, и многое другое. Поэтому использование чистых функций и возвращение новых экземпляров состояния также значительно облегчает отладку.
Но главное преимущество, на мой взгляд, заключается в том, что, привязав все входные данные наших компонентов к свойствам состояния (), мы можем изменить стратегию обнаружения изменений () на , и это улучшит производительность приложения.
AngularJS Extends HTML
AngularJS extends HTML with ng-directives.
The ng-app directive defines an AngularJS application.
The ng-model directive binds the value of HTML controls
(input, select, textarea) to application data.
The ng-bind directive binds application data to the HTML
view.
AngularJS Example
<!DOCTYPE html>
<html><script
src=»https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js»></script>
<body><div ng-app=»»>
<p>Name: <input type=»text» ng-model=»name»></p>
<p ng-bind=»name»></p>
</div>
</body>
</html>
Example explained:
AngularJS starts automatically when the web page has loaded.
The ng-app directive tells AngularJS that the <div> element is the «owner» of an
AngularJS application.
The ng-model directive binds the value of the input field to
the application variable name.
The ng-bind directive binds the content of the <p> element to the application variable name.
Что делает Angular?
Angular — фреймворк JavaScript, который помогает разработчикам создавать приложения. Библиотека предоставляет множество фич, которые делают простые реализации сложных задач современных приложений, таких как привязка данных, маршрутизация и анимация.
Angular также представляет ряд конвенций о подходах к разработке приложений. Это может быть очень полезно для больших команд, которые должны работать вместе на одном проекте. Angular — это одна из немногих библиотек JavaScript, которые обеспечивают обширный style guide с большим количеством наглядных примеров того, как вы можете писать свой код, используя этот фреймворк.
Настроить всё вместе
Отлично, мы создали всё, что нужно нашему хранилищу, но нам пока не хватает одной вещи — собрать всё воедино. Я собираюсь сделать это в модуле , но вы можете применить то же самое в модуле вашего приложения.
Давайте посмотрим модуль приложения:
Файл с описанием модуля приложения
Давайте перечислим то, что необходимо для настройки нашего хранилища:
- Мы импортируем наши редукторы, и передаём их в метод модуля хранилища.
- Мы импортируем наши эффекты, и передаём их внутри массива в метод модуля эффектов.
- Мы передаём настройки для модуля состояния маршрутизатора .
- И мы добавляем инструменты разработчика хранилища , если запущена среда разработки.
Первые два шага необходимы, в то время как шаги 3 и 4 я настоятельно рекомендую, но они не являются обязательными.
Теперь мы наконец закончили … и можем использовать хранилище в наших компонентах!
AngularJS Directives
As you have already seen, AngularJS directives are HTML attributes with an ng prefix.
The ng-init directive initializes AngularJS application variables.
AngularJS Example
<div ng-app=»» ng-init=»firstName=’John'»>
<p>The name is <span ng-bind=»firstName»></span></p>
</div>
Alternatively with valid HTML:
AngularJS Example
<div data-ng-app=»» data-ng-init=»firstName=’John'»>
<p>The name is <span data-ng-bind=»firstName»></span></p>
</div>
You can use data-ng-, instead of ng-, if
you want to make your page HTML valid.
You will learn a lot more about directives later in this tutorial.
Пример использования NGRX
Итак, мы закончили с теорией, представив жизненный цикл и его участников, а теперь пришло время посмотреть на это в действии. Из этого легко сделать ещё одну статью. Но, на мой взгляд, нет смысла объяснять всё то, что мы объяснили без примеров реализации. Так мы можем посмотреть всё в действии, скачать и поиграться с кодом.
В нашем примере будет список пользователей, страница сведений о пользователе, и некоторая начальная информация о конфигурации, которую вы должны получить при запуске приложения. Мы собираемся реализовать некоторые важные этапы жизненного цикла .
Вот что это будет:
- Установить библиотеки
- Создать структуру папок для хранилища
- Создать состояние и начальные значения
- Создать действия
- Создать редукторы
- Создать эффекты
- Создать селекторы
- Собрать и настроить всё вместе
- Использовать хранилище в некоторых компонентах
Итак, приступим …
Что такое 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?
Технически вы можете использовать Angular где угодно, но лучше всего он работает в нестандартных приложениях с данными. Если вы ознакомитесь с различными приложениями Angular, собранными на madewithangular.com, вы увидите реальные приложения, которые собирают данные из форм и работают с ними.
Angular работает не только с формами. Разработчики создали множество игр при помощи Angular и такие сумасшедшие вещи, как приложения с дополненной реальностью. Однако, большинство туториалов и документации по Angular все равно содержат информацию о создании некоторых form-based приложений. Например, вы встраиваете документацию Angular в приложение, где вы создали героев и их список через форму.
Окончательный результат демо-приложения Tour of Heroes из Angular документации.
Angular хорош в form-based приложениях, он подходит для больших и сложных приложений. Angular — не самый простой и не самый маленький фреймворк JavaScript. Следовательно, если вы создаёте нечто небольшое, вам лучше подобрать для работы фреймворк попроще, например, jQuery. Angular хорошо подойдёт для разработчиков приложений в средних и больших командах. Если вы разрабатываете приложение самостоятельно, может показаться, что шаблонного кода и конвенций разработки в Angular намного больше, чем вам нужно.
Angular также хорошо подходит для приложений, которые должны работать в нескольких средах разработки. Если приложение должно работать на веб, а также на Windows или Maс, вы можете придерживаться одного из многочисленных туториалов для запуска Angular-приложений с популярным Electron project.
Если же у вас приложение, которое нужно запустить на веб, iOS или Android, можете использовать NativeScript для рендеринга вашего приложения в мобильной среде. В некоторых случаях вы даже можете распространять код через эти платформы, экономя ценное время разработки.
Как выглядит Angular-приложение?
Теперь, когда вы имеете некоторое представление об Angular, давайте углубимся в код. Начнём с небольшого приложения “hello world”. Все приложения Angular начинаются с НТМL-страницы, которая выглядит следующим образом.
В реальном приложении тег < script > внутри тега < head > может быть немного сложным, но в высокоуровневых приложениях он такой же, как и другие веб-приложениях – вы загружаете кусок JavaScript-кода в HTML-документ, и приложение работает.
Есть одна уникальная вещь в выше приведённом примере – элемент < my-app >. Вы не используете этот элемент регулярно в веб-приложении. Цель Angular – постоянно расширять словарь НТМL, позволяя вам определять собственные теги.
Такие пользовательские теги называют компонентами, и вы можете определять их поведение в коде. Вот простейшая реализация элемента < my-app >:
Есть несколько моментов, которые вам нужно знать, чтобы понять, что происходит в данном фрагменте кода. Первое – это код на TypeScript, а не на JavaScript. TypeScript может показаться вам пугающим, если вы не встречались с ним раньше, но его основы понять нетрудно.
TypeScript – надстройка над JavaScript, то есть весь синтаксис JavaScript доступен на TypeScript. Кстати, весь приведённый выше синтаксис – import, export, @Component и остальные – это или нынешние фичи JavaScript, или те, что появятся в ближайшем будущем. Так что, когда вы учите TypeScript, вы изучаете будущее JavaScript. TypeScript, к тому же, отличается превосходной документацией, к которой вы можете обратиться в любое время.
TypeScript был создан и поддерживается Microsoft. Он стал очень популярным за последние несколько лет, поэтому можете смело использовать его в разработке своих приложений. Он никуда не денется.
Давайте еще раз посмотрим на TypeScript-код, определяющий компонент < my-app >:
В Angular вы используете тег @Component, который известен как декоратор, чтобы отметить классы, которые учитывают элементы, которые могут быть использованы в вашей HTML-разметке. У вас есть возможность передавать свойства @Component для описания элемента.
- Свойство selector определяет имя тега при вводе в HTML. Использование селектора < my-app > показывает Angular, что делать, когда он видит тег < my-app > в HTML.
- Свойство template контролирует, что HTML должен делать, когда используется компонент. Пример использования template: «< h1 >Hello World< /h1 >», тут видно, как Angular определяет, какие действия применять при < my-app > и почему это приложение представляет базовый тег < h1 > при предварительном просмотре в браузере.
Отображение базового примера “Hello World” в браузере.
Создание компонента Angular¶
Компоненты представляют основные строительные блоки приложения Angular. Каждое приложение Angular имеет как минимум один компонент. Поэтому создадим в папке новый файл, который назовем и в котором определим следующий код компонента:
В начале файла определяется директива , которая импортирует функциональность модуля , предоставляя доступ к функции декоратора .
Далее собственно идет функция-декоратор , которая ассоциирует метаданные с классом компонента . В этой функции, во-первых, определяется параметр или селектор для HTML-элемента, который будет представлять компонент. Во-вторых, здесь определяется параметр или шаблон, который указывает, как надо визуализировать компонент. В этом шаблоне задана двусторонняя привязка с помощью выражений и к некоторой модели .
И в конце экспортируется класс компонента , в котором как раз определяется модель — в данном случае это пустая строка.
Структурные директивы ngIf, ngFor, ngSwitch
Последнее обновление: 13.11.2020
Структурные директивы изменяют структуру DOM с помощью добавления или удаления html-элементов. Рассмотрим три структурных директивы: ngIf, ngSwitch
и ngFor.
ngIf
Директива ngIf позволяет удалить или, наоборот, добавить элемент при определенном условии. Например, определим следующий компонент:
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<p *ngIf="condition"> Привет мир </p> <p *ngIf="!condition"> Пока мир </p> <button (click)="toggle()">Toggle</button>` }) export class AppComponent { condition: boolean=true; toggle(){ this.condition=!this.condition; } }
В зависимости от значения свойства будет отображаться либо первый, либо второй параграф.
Мы можем задавать альтернативные выражения с помощью директивы ng-template. Так, предыдущий пример будет аналогичен следующему:
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<p *ngIf="condition;else unset"> Привет мир </p> <ng-template #unset> <p>Пока мир</p> </ng-template> <button (click)="toggle()">Toggle</button>` }) export class AppComponent { condition: boolean=true; toggle(){ this.condition=!this.condition; } }
Выражение указывает, что если condition равно false, то срабатывает блок .
Либо можно определить более изощренную логику. Так, изменим шаблон компонента следующим образом:
template: ` <div *ngIf="condition; then thenBlock else elseBlock"></div> <ng-template #thenBlock>Then template</ng-template> <ng-template #elseBlock>Else template</ng-template> <button (click)="toggle()">Toggle</button>`
В данном случае, если condition равно true, то отображается блок thenBlock, иначе отображается блок elseBlock.
ngFor
Директива ngFor позволяет перебрать в шаблоне элементы массива. Например:
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<ul> <li *ngFor="let item of items">`item`</li> </ul>` }) export class AppComponent { items =; }
В качестве значения директива принимает значение перебора аля-foreach: . Каждый перебираемый элемент помещается в
переменную , которую мы можем вывести на страницу.
При переборе элементов нам доступен текущий индекс элемента через переменную index, которую мы также можем использовать. Например:
<div> <p *ngFor="let item of items; let i = index">{{i+1}}.`item`</p> </div>
Надо учитывать, что индексация идет с нуля, поэтому, чтобы в данном случае отсчет шел с единицы, к переменной i прибавляется единица.
Символ звездочки и синтаксический сахар
Можно заметить, что при использовании директив ngFor и ngIf перед ними ставится символ звездочка. По факту это не более чем синтаксический сахар, который упрощает применение
директивы. Так, определение :
<p *ngIf="condition"> Привет мир </p> <p *ngIf="!condition"> Пока мир </p>
по факту будет представлять следующий код:
<ng-template ="condition"> <p> Привет мир </p> </ng-template> <ng-template ="!condition"> <p> Пока мир </p> </ng-template>
В итоге параграф и его текст перемещаются внутрь элемента .
Сама директива помещается в тег , в котором применяется привязка свойства. Булевое значение привязанного свойство указывает, надо ли
отображать соответствующий контент.
В итоге мы можем выбирать либо первый способ со звездочкой, который более компактный, либо второй способ с элементами ng-template.
То же самое касается и директивы ngFor:
<ul> <li *ngFor="let item of items">`item`</li> </ul>
Этот код будет эквивалентен следующему:
<ul> <ng-template ngFor let-item ="items"> <li>`item`</li> </ng-template> </ul>
ngSwitch
С помощью директивы ngSwitch можно встроить в шаблон конструкцию switch..case и в зависимости от ее результата выполнения выводить тот или иной блок. Например:
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<div ="count"> <ng-template ngSwitchCase="1">{{count * 10}}</ng-template> <ng-template ngSwitchCase="2">{{count * 100}}</ng-template> <ng-template ngSwitchDefault>{{count * 1000}}</ng-template> </div>` }) export class AppComponent { count: number = 5; }
Директива ngSwitch в качестве значения принимает некоторое выражение. В данном случае это свойство count. В элемент
помещается инструкция , которая сравнивает значение выражения из ngSwitch с другим выражением. Если оба выражения равны, то
используется данный элемент template. Иначе выполнение переходит к следующим инструкциям ngSwitchCase. Если же ни одна из инструкций ngSwitchCase не была выполнена,
то вызывается инструкция .
НазадВперед
AngularJS Expressions
AngularJS expressions are written inside double braces: ` expression `.
AngularJS will «output» data exactly where the expression is written:
AngularJS Example
<!DOCTYPE html>
<html><script
src=»https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js»></script><body><div ng-app=»»>
<p>My first expression: {{ 5 + 5 }}</p>
</div>
</body>
</html>
AngularJS expressions bind AngularJS data to HTML the same way as the ng-bind
directive.
AngularJS Example
<!DOCTYPE html>
<html>
<script
src=»https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js»></script>
<body><div ng-app=»»> <p>Name:
<input type=»text» ng-model=»name»></p> <p>`name`</p></div>
</body>
</html>
You will learn more about expressions later in this tutorial.
Построение проекта
Последнее обновление: 12.11.2020
В прошлой теме был создан первый простейший проект.
Мы можем его запустить, поработать с ним, изменять его код, но как теперь получить те файлы, которые собственно представляют приложение и которые мы можем разместить на каком либо сервере?
Для этого нам надо выполнить построение проекта.
В прошлой теме мы определили следующий файл angular.json:
{ "version": 1, "projects": { "helloapp": { "projectType": "application", "root": "", "sourceRoot": "src", "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { "outputPath": "dist/helloapp", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.json", "aot": true } }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "helloapp:build" } } } }}, "defaultProject": "helloapp" }
Секция описывает конфигурацию команды построения «ng build». В частности, параметр
задает каталог для компилируемых файлов приложения.
То есть мы можем ввести в командную строку команду «ng build» для компиляции проекта
C:\angular\helloapp>ng build
После выполнения этой команды в каталоге проекта появится папка dist/helloapp, где мы сможем увидеть все файлы приложения. Мы можем расположить эти файлы на любой веб-сервер и так же обращаться к главной странице приложения.
Здесь мы видим, что у нас получается много файлов, в том числе файлы с расширением .js.map, которые нам в принципе могут быть не нужны.
А основные файлы имеют довольно большой размер. Тем не менее мы можем все это оптимизировать. Так, изменим файл angular.json следующим образом:
{ "version": 1, "projects": { "helloapp": { "projectType": "application", "root": "", "sourceRoot": "src", "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { "outputPath": "dist/helloapp", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.json", "aot": true }, "configurations": { "production": { "optimization": true, "outputHashing": "all", "sourceMap": false, "namedChunks": false, "vendorChunk": false, "buildOptimizer": true } } }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "helloapp:build" } } } }}, "defaultProject": "helloapp" }
Теперь мы добавили для команды build подсекцию «configurations», которая задает дополнительные конфигурации проекта. И здесь указана однак конфигурация —
«production» — то есть набор настроек, которые применяются к построению приложения, когда оно уже готово к развертыванию и полноценному использованию. И здесь определяется следующий набор настроек:
-
: указывает, будет ли использоваться оптимизация
-
: указывает, будет ли в название генерируемого файла добавляться хеш-значение. Значение
говорит, что в названия всех генерируемых файлов добавляется хеш -
: определяет, будут ли генерироваться файлы sourceMap
-
: определяет, будут ли использоваться имена файлов для именнованных подгружаемых чанков
-
: определяет, будет ли создаваться для сторонних используемых в приложении библиотек отдельный файл
-
: подключает пакет
для оптимизации при использовании опции
Стоит отметить, что эти конфигурации никак не влияют на процесс разработки и тестирования приложения. Мы также сможем запускать проект при помощи команды «ng serve». Она не будет применять никаких оптимизаций из конфигурации «production»,
иначе это бы увеличило процесс перекомпиляциии приложения при каждом изменении кода.
Теперь при компиляции используем конфигурацию production. Для этого команде build надо передать флаг :
C:\angular\helloapp>ng build --prod
После этого мы увидим в папке dist/helloapp более компактные файлы, которые собственно и представляют приложение и которые мы можем разместить на каком-нибудь
веб-сервере и обращаться к ним.
НазадВперед
Angular.json¶
Для компиляции приложения мы будем использовать Angular CLI, поэтому нам надо описать поведение CLI с помощью файла . Итак, добавим в корневую папку проекта новый файл и определим в нем следующее содержимое:
Вкратце пройдемся по структуре файле. Вначале определяется параметр . Он определяет версию конфигурации проекта.
Далее идет секция , которая определяет настройки для каждого проекта. В нашем случае у нас только один проект, который называется по названию каталога проекта — .
Проект определяет следующие опции:
- : тип проекта. Значение «» указывает, что проект будет представлять приложение, которое можно будет запускать в браузере
- : указывает на папку файлов проекта относительно рабочей среды. Пустое значение соответствует корневой папке проекта, так как в данном случае рабочая среда и каталог проекта совпадают
- : определяет корневую папку файлов с исходным кодом. В нашем случае это папка , где собственно определены все файлы приложения
- : задает настройки для построения проекта. В файле определены команды и , и для каждой из этих команд в секции заданы свои настройки.
Для каждой команды задается параметр , который определяет инструмент для построения проекта. Так, для команды «» задано значение «» — данный билдер для построения использует сборщик пакетов webpack. А для команды «» задано значение «» — данный билдер запускает веб-сервер и развертывает на нем скомпилированное приложение.
Параметр задает параметры построения файлов. Для команды «» здесь определены следующие опции:
- : путь, по которому будет публиковаться скомпилированное приложение
- : путь к главной странице приложения
- : путь к главному файлу приложения, где собственно запускается приложение Angular
- : путь к файлу полифилов
- : путь к файлу конфигурации TypeScript
- : указывает, будет ли использоваться компиляция AOT (Ahead-Of-Head) (предварительная компиляция перед выполнением). В данном случае значение означает, что она используется
Для команды «» указана только одна опцияя — , которая содержит ссылку на конфигурацию для команды — «». То есть по сути эта команда использует ту же конфигурацию, что и команда .
Последняя опция указывает на проект по умолчанию. В данном случае это наш единственный проект.
Если мы используем TypeScript для работы с Angular и Angular CLI для компиляции, то эти файлы , и фактически будут присутствовать в каждом проекте. И их можно переносить из проекта в проект с минимальными изменениями. Например, в файле вместо названия проекта «» будет соответствующее название проекта. В файле можно будет задать какие-то другие версии пакетов, если предыдущие версии устарели. Можно будет изменить название проекта, версию. Можно подправить настройки TypeScript или Angular CLI, но в целом общая организация будет той же.
В итоге у нас получится следующая структура проекта:
Действия (actions), редукторы (reducer), селекторы (select), хранилище (store) и побочные эффекты (effects) NGRX
Это основные строительные единицы жизненного цикла . Каждый из них берет на себя часть процесса от запуска операции до изменения нашего состояния и извлечения данных.
На этой картинке мы видим жизненный цикл ngrx. Давайте разберём его …
1. В наиболее распространенном сценарии все начинается в представлении компонента (). Взаимодействие с пользователем может привести к тому, что компонент отправит действие ().
2.1. Если действие не вызывает эффект (), то редуктор отфильтрует действие (обычно с помощью оператора switch), и вернёт новое состояние, которое будет результатом слияния старого состояния со значением, которое изменилось после вызова действия.
2.2. Если действие вызвало эффект, то это говорит о необходимости обработки побочных эффектов перед вызовом редуктора. Это может быть что-то вроде вызова службы HTTP для получения данных.
2.2.1. После того, как эффект отработал (побочные эффекты закончились), он запускает новое действие «состояние-результат» (побочные эффекты могут быть успешными или неудачными), и мы возвращаемся к пункту 2.1.
3. Теперь у хранилища есть новое состояние. Состояние может быть большим деревом — объектом, поэтому вводит селекторы, чтобы иметь возможность использовать только необходимые фрагменты объекта.
Какую версию Angular мне лучше использовать?
На данный момент существует две популярные версии Angular. Версия 1 доступна на https://angularjs.org/ и является обновлённой версией того Angular, что был представлен Miško и его командой в 2011 году. Другая популярная версия теперь называется просто Angular и доступна на https://angular.io/. Современный Angular – это полностью переделанная версия для новых браузеров, рабочих процессов и платформ разработки.
Почти во всех случаях вам следует придерживаться последней версии Angular. В ближайшем будущем команда Angular будет стремиться поддерживать Angular 1, но нет никаких оснований полагать, что они будут поддерживать и более старые версии. Более того, Angular 1 не допускает использования библиотеки вне браузера, поэтому вы не можете воспользоваться такими библиотеками, как NativeScript для создания мобильных приложений.
Структура папок хранилища
Давайте начнем с обсуждения файловой структуры хранилища. Эта файловая структура и вся конфигурация хранилища должны быть в модуле вашего приложения. Но в нашем примере у нас его нет, поэтому хранилище будет расположено в модуле (действия в значительной степени совпадают, если расположить его в модуле).
Структура папок хранилища
Структура папок представляет фактическую структуру объекта хранилища. У вас будет главная папка с названием «store» и пять вложенных папок, которые представляют каждого из ключевых игроков хранилища: «Actions», «Effects», «Reducers», «Selectors» и «State».
… и недостатки
- У , конечно, есть кривая обучения. Не большая, но и не такая маленькая, и я думаю, что это требует некоторого опыта или глубокого понимания некоторых программных шаблонов. Это не является проблемой для любого разработчик среднего уровня, но младший может поначалу немного запутаться.
- Для меня это ощущается немного многословно (прим пер.: речь о проблеме множества заготовок кода — ). Поэтому каждый раз, когда вы добавляете какое-либо свойство в состояние (), вам нужно добавлять действия () и диспетчеры (). Вам может потребоваться обновить или добавить селекторы (), эффекты (), если таковые имеются, и обновить хранилище (). Кроме того, вы будете собирать конвейер () операторов и наблюдаемых потоков () везде где это потребуется.
- не является частью библиотек , и не поддерживается Google. По крайней мере, не напрямую, потому что среди контрибьюторов есть разработчики из команды . Это ещё один пункт для обдумывания — вы добавляете в зависимости тяжёлую библиотеку.
Создание эффектов
Вы, наверное, уже заметили, что в редукторах мы не обрабатываем все действия, которые мы создали. Это потому, что мы собираемся обработать пропущенные действия в эффектах, потому что эти действия имеют побочные эффекты.
Давайте начнем с пользовательских эффектов :
Файл с описанием эффектов пользователя
В этом файле у нас много чего происходит. Давайте попробуем объяснить это:
- Мы объявляем наши пользовательские эффекты с помощью декоратора внедряемых зависимостей .
- Мы объявляем наши эффекты, используя декоратор эффектов, предоставленный библиотекой .
- Используя действия, предоставляемые , мы собираемся собрать конвейер наших операторов для этого эффекта.
- Следующим шагом является определение типа действия в эффекте с помощью оператора .
- Следующие части представляют собой операторы , которые мы используем для получения того, что нам нужно (Документация ngrx Справочник RxJS).
- Наконец, в последнем операторе собирается отправить другое действие
- В конструкторе мы внедряем сервисы, которые собираемся использовать, действия для и, в данном случае, хранилище (учтите, что это демонстрационная версия, и мы получаем выбранного пользователя из списка пользователей в нашем локальном хранилище)
Это в значительной степени та же самая структура, которую вы увидите в любом описании эффекта. В этом случае мы отправляем только успешное действие, но мы можем отправлять ошибки или любое другое состояние, которое мы хотим обработать в наших редукторах приложений.
Давайте посмотрим на эффекты конфигурации :
Файл с описанием эффекта конфигурации
И снова, вы, вероятно, чувствуете себя комфортно читая этот код.
Теперь пришло время поговорить о селекторах …