Изучаем angularjs на пяти практических примерах

Когда использовать NGRX

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

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

При этом я считаю, что сильная команда разработчиков может решить использовать в проекте потому что они знают силу шаблона и операторов . И они чувствуют себя комфортно, работая и с тем, и с другим …

Как устроен Angular: компоненты

Angular-приложения состо­ят из неза­ви­си­мых эле­мен­тов. Эти эле­мен­ты назы­ва­ют­ся ком­по­нен­та­ми, и у каж­до­го ком­по­нен­та своё поведение. 

Напри­мер, лен­та ново­стей — один ком­по­нент. Отве­ча­ет за отоб­ра­же­ние спис­ка ново­стей на стра­ни­це. Кноп­ка «Про­чи­тать» — дру­гой ком­по­нент. Отве­ча­ет за пере­ход со стра­ни­цы спис­ка ново­стей к выбран­ной новости. 

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

Ком­по­нен­ты под­чи­ня­ют­ся жиз­нен­ным цик­лам — меня­ют­ся и рабо­та­ют по несколь­ким запро­грам­ми­ро­ван­ным сце­на­ри­ям. Возь­мём ситу­а­цию, когда мы пере­хо­дим со стра­ни­цы спис­ка ново­стей к одной ново­сти. В этом слу­чае ком­по­нент «Лен­та ново­стей» уни­что­жа­ет­ся и при необ­хо­ди­мо­сти созда­ёт­ся повтор­но. Жиз­нен­ные цик­лы раз­гру­жа­ют память и уско­ря­ют приложение.

Стра­ни­ца с шап­кой, лен­той ново­стей и тре­мя кноп­ка­ми. Каж­дый эле­мент — неза­ви­си­мый ком­по­нент, кото­рый выпол­ня­ет какое-то дей­ствие внут­ри приложения 

Популярные встроенные 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.

Какую версию Angular мне лучше использовать?

На данный момент существует две популярные версии Angular. Версия 1 доступна на https://angularjs.org/  и является обновлённой версией того Angular, что был представлен Miško и его командой в 2011 году. Другая популярная версия теперь называется просто Angular и доступна на https://angular.io/. Современный Angular – это полностью переделанная версия для новых браузеров, рабочих процессов и платформ разработки.

Почти во всех случаях вам следует придерживаться последней версии Angular. В ближайшем будущем команда Angular будет стремиться поддерживать Angular 1, но нет никаких оснований полагать, что они будут поддерживать и более старые версии. Более того, Angular 1 не допускает использования библиотеки вне браузера, поэтому вы не можете воспользоваться такими библиотеками, как NativeScript для создания мобильных приложений.

Пример NGRX

  1. Установка библиотеки
  2. Создание структуры папок для хранилища
  3. Создание хранилища и начальных значений
  4. Создание действий (Actions)
  5. Создание редукторов (Reducers)
  6. Создание эффектов (Effects)
  7. Создание селекторов (Selectors)
  8. Конечная настройка
  9. Использование хранилища в компонентах

Создание хранилища и начальных значений

  1. Мы создаем и экспортируем интерфейс со структурой пользовательской среды.
  2. Мы делаем то же самое с начальным пользовательским состоянием, которое реализует недавно созданный интерфейс.
  1. Состояние приложения содержит состояние пользователя и конфигурации, а также состояние маршрутизатора.
  2. Потом задаем начальное состояние приложения.
  3. Наконец, экспортирует функцию, чтобы получить начальное состояние (мы будем использовать его позже).

Создание Действий

  1. Мы экспортируем Enum, содержащий определение для типов действий. Таким образом, мы избегаем использования и повторения строк для использования типов действий, процесс, который может легко порождаться ошибками.
  2. Потом мы создаем и экспортируем класс для каждого из ваших действий. Все они должны реализовать интерфейс Action из ngrx. Наконец, мы устанавливаем тип в одно из значений перечислений, и если вам нужно полезное содержимое для действия, вы добавляете его в конструктор класса.
  3. Наконец, мы экспортируем тип, содержащий наши классы действий. Это обеспечит нам проверку типов, которую мы можем использовать, например, в наших редукторах.

Создание Редукторов

  1. Объявление редуктора получает состояние и, в этом случае, действия пользователя и возвращает IUserState.
  2. Используя оператор switch, мы генерируем наблюдения для каждого возможного типа действия.
  3. Каждый случай возвращает новый объект, который является результатом слияния старого состояния и нового значения.
  4. Все редукторы имеют результат по умолчанию, который просто возвращает состояние без каких-либо изменений.

Добавим Эффекты

  1. Мы объявляем наши пользовательские эффекты с помощью инъекционного декоратора.
  2. Мы объявляем наши эффекты, используя декоратор эффектов, предоставленный ngrx/Effects.
  3. Используя действия, предоставленные ngrx / Effects, мы собираемся запустить конвейер нашего оператора для этого эффекта.
  4. Следующим шагом является установка типа действия эффекта с помощью оператора ofType.
  5. Следующие части представляют собой операторы rxjs, которые мы используем для получения того, что нам нужно (у нас уже есть ссылка на документацию по rxjs в этой статье).
  6. Наконец, в последнем операторе Effect отправит еще одно действие.
  7. В конструкторе мы внедряем сервисы, которые мы собираемся использовать, действия для ngrx / Effects, и в этом случае также хранилище (учтите, что это демо, и мы получаем выбранного пользователя из списка пользователей в наше хранилище).

Итоговая настройка

  1. Мы импортируем наши редукторы и предоставляем их в forRoot модуля хранилища.
  2. Мы импортируем наши эффекты и предоставляем их внутри массива в модуль forRoot эффектов.
  3. Мы устанавливаем конфигурацию для модуля состояния маршрутизатора, предоставляющего маршрутизатор stateKey.
  4. И мы добавляем инструменты разработчика магазина, если среда не является производственной.

Использование хранилища в некоторых компонентах

Во-первых, давайте получим конфигурацию при запуске приложения:

  1. Мы добавляем хранилище в наш app.component.
  2. Мы устанавливаем для свойства компонента значение селектора в конфигурации, потому что хотим отобразить часть этой информации в HTML.
  3. В onInit мы отправляем действие, чтобы получить конфигурацию.
  1. Подобно тому, как мы управляем конфигурацией, мы собираемся получить список пользователей. Сначала мы внедряем хранилище в компонент пользователя.
  2. На onInit мы отправляем действие, чтобы получить пользователей.
  3. Мы создаем свойство для компонента и присваиваем ему список пользователей, используя селектор списка пользователей.

Давайте посмотрим на компонент пользовательского контейнера:

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 ❯

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.

Важные вещи россыпью

  • Ужасная документация. Приходится дополнительно гуглить много информации.
  • До сих пор отсутствуют директивы для Drag and Drop событий (на момент написания этой статьи). Само по себе это не очень большая проблема, но это сигнализирует о продуманности продукта и внимании к деталям. Эти события уже поддерживаются десктопных браузеров и являются таким же базовыми, как и onclick или mousemove.
  • Когда вы пишите на ангуляре вы помещаете логику в ваш HTML. ng-repeat, ng-show, ng-class, ng-model, ng-init, ng-click, ng-switch, ng-if — что это как не помещение логики в представление. Само наличие такой логики — это не настолько страшно, как то что — это невозможно тестировать юнит-тестами (а это самые очень важные части приложения), невозможно продебажить и оттуда не кидаются ошибки (непродуманная-архитектура#12).
  • Гугл не использует AngularJs для своих основных продуктов (gmail, google+). И это вызывает подозрения, если это такой хороший фрейворк и они сами его создали, что тогда сами и не используют? Хотя например изобретенный в фейсбуке ReactJs они используют в facebook.com и в инстаграмме. Я знаю, что гугловцы используют этот ангуляр для других более мелких проектов, но все таки они не используют его в самых главных.

Что такое 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»
также будет динамически изменять свое значение.

Чуть ниже в элементе выводится значение этой модели.

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

Вперед

Иерархическое внедрение зависимостей

Я уже упоминал, что Angular2-приложение — это дерево компонентов. И у каждого компонента есть свой роутер и инжектор. Таким образом дерево инжекторов и компонентов параллельны.

Какие плюсы даёт такой подход? Например, теперь легко можно настроить один и тот же сервис по-разному, в зависимости от компонента, в который он внедряется. При этом, можно не бояться как-то повлиять на другие компоненты выше или на том же уровне иерархии, так как они будут использовать другие экземпляры того же сервиса. Компонент теперь не зависит от того, как был сконфигурирован какой-то сервис. Если компоненту нужен отдельный экземпляр сервиса, он просто добавляет его в секцию .

Заметьте, в коде сервисов нет нигде упоминания о провайдерах. Мы не можем зарегистрировать какой-то провайдер в рамках какого-нибудь сервиса. Если в сервис внедряется другой сервис, его провайдер регистрируется в каком-то компоненте. Мы не сможем внедрить сервис без компонента. Таким образом, ещё раз подчёркивается компонентный подход всего фреймворка: сервисный слой стал вторичным, на первое место вышли компоненты. И у каждого компонента могут быть свои личные изолированные от других экземпляры сервисов.

Разумеется, ангуляр не создаёт для каждого компонента отдельный инжектор. Это было бы довольно неэффективно. Но в любом случае, каждый компонент имеет свой инжектор, даже если делит его с другим компонентом.

Как происходит выбор нужного экземпляра зависимости? У каждого компонента зависимость либо прописана в секции , либо должна быть найдена выше по иерархии. Для инжектора корневого компонента выше по иерархии стоит только глобальный инжектор, который создаётся при вызове функции .
Если поле не пустое, инжектор компонента становится равным результату выполнения статического метода , который резолвит переданный массив провайдеров и создаёт новый экземпляр инжектора. У каждого инжектора есть поле , которое содержит ссылку на родительский инжектор. Если компоненту требуется зависимость, инжектор компонента пытается найти нужную у себя. Если не находит, пытается найти в родительских инжекторах вплоть до корневого.

Вот пример того, как работают инжекторы с иерархией:

Тут 2 сервиса и 2 компонента. В родительском компоненте регистрируются 2 сервиса ( и ), в дочернем — только . Если понажимать на кнопки , то одинаковые массивы будут только у , так как дочерний компонент, не найдя у себя зависимость использует инстанс, полученный из родительского компонента. А вот экземпляр у дочернего компонента создастся новый. Поэтому дочерний компонент будет писать в свой экземпляр, а родительский — в свой.

Означает ли это, что сервисы в Angular2 не являются синглтонами? В конкретном инжекторе не может быть больше 1-го инстанса сервиса. Но так как самих инжекторов может быть несколько, то и разных инстансов одного и того же сервиса во всём приложении может быть больше одного.

От переводчиков

Всем привет, с вами Максим Иванов и Дмитрий Сергиенков, и сегодня мы выясним куда делась третья версия, и почему мы по-прежнему можем быть верны Angular. Сейчас начинающему фронтенд-разработчику, изучающему JavaScript, довольно трудно определиться: какой же фреймворк или библиотеку им взять и изучить, оставаясь в тренде? Конечно, без слова React, сейчас не обходится ни один разговор на тему фронтенда, однако, в свое время я начал с первой версии Angular, начитался много руководств по написанию фронтенда на ES6 (с классами и прочим добром) и до сих пор не жалею. Да, вы можете писать корпоративные приложения с использованием только jQuery, но по мере развития и сложности проекта вы начнете закапывать себя в спагетти-коде, смешивая логику и представление, MV*-фреймворки же этого сделать вам не дадут.

Пример использования NGRX

Итак, мы закончили с теорией, представив жизненный цикл и его участников, а теперь пришло время посмотреть на это в действии. Из этого легко сделать ещё одну статью. Но, на мой взгляд, нет смысла объяснять всё то, что мы объяснили без примеров реализации. Так мы можем посмотреть всё в действии, скачать и поиграться с кодом.

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

Вот что это будет:

  • Установить библиотеки
  • Создать структуру папок для хранилища
  • Создать состояние и начальные значения
  • Создать действия
  • Создать редукторы
  • Создать эффекты
  • Создать селекторы
  • Собрать и настроить всё вместе
  • Использовать хранилище в некоторых компонентах

Итак, приступим …

Загрязнение ngOnInit

— один из самых важных хуков жизненного цикла в компонентах Angular. Он используется для инициализации данных, настройки слушателей, создания соединений и т.д. Однако в некоторых случаях он перегружает хук жизненного цикла:

Рассмотрим этот компонент. У него есть всего два жизненных цикла. Однако метод выглядит ужасно. Он подписывается на различные события изменения формы, потоки , а также загружает много данных. Он состоит из 40 строк кода, а если включить опущенное здесь содержимое обратных вызовов , то мы получим более 100 строк, что противоречит даже самым мягким рекомендациям. Чтобы добраться до других методов, помимо придется прокручивать весь этот беспорядочный кусок кода (или закрывать/открывать его при необходимости). Более того, из-за большого количества смешанных концепций и задач усложняется поиск элементов внутри самого метода .

Теперь рассмотрим исправленную версию того же компонента:

Логика компонента сохраняется, меняется лишь способ организации кода. Теперь метод вызывает три различных метода для загрузки начальных данных из сервисов, установки прослушивателей изменения формы и прослушивателей событий DOM (при необходимости). Эти изменения упрощают чтение компонента с первого раза (прочтите — разберитесь, с чего он начинается, и если вам нужны подробности реализации, просмотрите соответствующие методы). Поиск источника ошибок также упрощается: если прослушиватели форм работают неправильно, перейдите в и т.д.

Не загрязняйте метод  — разделите его на несколько частей!

Кто поддерживает Angular?

Angular Core Team состоит из большого количества людей во всем мире и из сообщества Angular. При этом большая часть разработок Angular изо дня в день осуществляется сотрудниками Google. Примерно 20 сотрудников Google входят в Angular Core Team и все ТОП-разработчики проекта Angular являются сотрудниками Google.

Следует отметить, что, несмотря на контроль Google над Angular, сам фреймворк по-прежнему много в чём зависит от усилий сообщества. Более двух тысяч человек внесли свой вклад в open-source репозиторий Angular, в общем доступе есть бесчисленные туториалы и guides, многочисленные компании предлагают обучение и набор инструментов для разработчиков.

Если контроль над проектом принадлежит одной компании, это неплохо, так как снижает конфликтные вопросы при принятия нестандартных решений.

Подводные камни Angular Universal

Не трогайте DOM

Когда мы начали тестировать компоненты нашего магазина с помощью , нам пришлось потратить некоторое время, чтобы понять, почему наш сервер падает при запуске без вывода серверной страницы. Например, у нас есть компонент Session Flow component, который отслеживает активность пользователя во время сессии (перемещения пользователя, клики, рефферер, информация об устройстве пользователя и т.д.). После поиска информации в issues на мы поняли, что в нет обертки над DOM.

.

Если вы склонируете этот Angular Universal стартер и откроете browser.module.ts вы увидите, что в массиве разработчики Universal предоставляют два:

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

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

Если вы хотите активно взаимодействовать с элементами DOM, используйте сервисы API, такие как, или .

Правильный роутинг

Поскольку сервер отражает наше приложение, у нас была проблема с роутингом.

Поэтому не забудьте добавить тот же роутинг на сервере что и на клиенте. Например, у нас есть такие роуты на клиенте:

Тогда нужно создать файл с массивом роутов сервера. Корневой маршрут можно не добавлять:

Наконец, добавьте роуты на сервер:

Пререндеринг стартовой страницы

Одной из наиболее важных особенностей является пререндеринг. Из исследования Kissmetrics следует, что 47% потребителей ожидают, что веб-страница загрузится за 2 секунды или даже менее

Для нас было очень важно отобразить страницу как можно быстрее. Таким образом, пререндеринг в как раз про нашу задачу

Давайте подробнее рассмотрим, что это такое и как его использовать.

Когда пользователь открывает URL нашего магазина, немедленно возвращает предварительно подготовленную HTML страничку с контентом, а уже затем затем начинает загружать все приложение в фоновом режиме. Как только приложение полностью загрузится, подменяет изначальную страницу нашим приложением. Вы спросите, что будет, если пользователь начнет взаимодействовать со страницей до загрузки приложения? Не беспокойтесь, библиотека Preboot.js запишет все события, которые выполнит пользователь и после загрузки приложения выполнит их уже в приложении.

Чтобы включить пререндеринг, просто добавьте в конфигурацию сервера :

Добавление мета-тегов

В случае SEO-ориентированного сайта добавление мета-тегов очень важно. Например, у нас есть , который представляет страницу определенного продукта

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

Команда создала сервис angular2-meta, чтобы легко манипулировать мета-тегами. Вставьте мета-сервис в ваш компонент и несколько строк кода добавлят мета-теги в вашу страницу:

В следующей версии Angular этот сервис будет перемещен в@angular/platform-server

Кэширование данных

запускает ваш XHR запрос дважды: один на сервере, а другой при загрузке приложения магазина.

Но зачем нам нужно запрашивать данные на сервере дважды? PatricJs создал пример, как сделать Http-запрос на сервере один раз и закэшировать полученные данные для клиента. Посмотреть исходный код примера можно . Чтобы использовать его заинжекте и вызовите метод для выполнения http-вызовов с кешированием:

… и недостатки

  • У , конечно, есть кривая обучения. Не большая, но и не такая маленькая, и я думаю, что это требует некоторого опыта или глубокого понимания некоторых программных шаблонов. Это не является проблемой для любого разработчик среднего уровня, но младший может поначалу немного запутаться.
  • Для меня это ощущается немного многословно (прим пер.: речь о проблеме множества заготовок кода — ). Поэтому каждый раз, когда вы добавляете какое-либо свойство в состояние (), вам нужно добавлять действия () и диспетчеры (). Вам может потребоваться обновить или добавить селекторы (), эффекты (), если таковые имеются, и обновить хранилище (). Кроме того, вы будете собирать конвейер () операторов и наблюдаемых потоков () везде где это потребуется.
  • не является частью библиотек , и не поддерживается Google. По крайней мере, не напрямую, потому что среди контрибьюторов есть разработчики из команды . Это ещё один пункт для обдумывания — вы добавляете в зависимости тяжёлую библиотеку.

Объект Observable и библиотека RxJS

Последнее обновление: 13.11.2020

Методы класса HttpClient после выполнения запроса возвращают объект Observable<any>,
который определен в библиотеке RxJS («Reactive Extensions»). Она не является непосредственно
частью Angular, однако широко используется особенно при взаимодействии с сервером по http. Эта библиотека реализует паттерн «асинхронный наблюдатель»
(asynchronous observable). Так, выполнение запроса к серверу с помощью класса HttpClient выполняются в асинхронном режиме.

Естественно чтобы задействовать функционал RxJS в приложении, в проект должна быть добавлена соответствующая зависимость «rxjs»:

{
    "name": "helloapp",
    "version": "1.0.0",
    "description": "First Angular 11 Project",
    "author": "Eugene Popov <metanit.com>",
    "scripts": {
        "ng": "ng",
		"start": "ng serve",
		"build": "ng build"
    },
    "dependencies": {
        "rxjs": "~6.6.3",
		// остальное содержимое секции
    },
    "devDependencies": {
        // содержимое секции
    }
}

Используя специальные методы для объекта Observable, например, map и filter, можно произвести некоторую постобработку
полученных от сервера результатов.

Например, определим в файле users.json данные, которые напрямую не соответствуют массиву объектов User:

{ 
	"userList":
	
}

В качестве модели данных используем класс User:

export class User{
	name: string;
	age: number;
}

То есть в данном случае у нас нет соответствия по именам свойствам: name — username и age — userage.

Определим следующий код сервиса, который будет получать данные из users.json:

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {User} from './user';
import {Observable} from 'rxjs';
import { map } from 'rxjs/operators';
  
@Injectable()
export class HttpService{
  
    constructor(private http: HttpClient){ }
      
    getUsers() : Observable<User[]> {
        return this.http.get('assets/users.json').pipe(map(data=>{
            let usersList = data;
            return usersList.map(function(user:any) {
                return {name: user.userName, age: user.userAge};
              });
        }));
    }
}

Смысл использования специального сервиса для работы с http заключается в сокрытии деталей отправки запросов.
Компонент же ожидает получить какие-то конкретные данные, например, в виде набора объектов User. С помощью метода map библиотеки rxjs можно
преобразовать данные из одного формата в другой.

У результата метода мы можем вызвать метод pipe(), который позволяет обработать результаты запроса. Для этого
метод pipe в качестве первого параметра принимает функцию обработки данных запроса. В данном случае в роли такой функции выступает оператор map,
который преобразует результаты запроса в новые объекты.

Но чтобы использовать элементы библиотеки RxJS, их надо импортировать:

import {Observable} from 'rxjs';
import { map } from 'rxjs/operators';

В итоге весь метод возвращает объект .

Теперь используем сервис в классе компонента:

import { Component, OnInit} from '@angular/core';
import { HttpService} from './http.service';
import {User} from './user';
  
@Component({
    selector: 'my-app',
    template: `<ul>
                <li *ngFor="let user of users">
                <p>Имя пользователя: {{user?.name}}</p>
                <p>Возраст пользователя: {{user?.age}}</p>
                </li>
            </ul>`,
    providers: 
})
export class AppComponent implements OnInit { 
  
    users: User[]=[];
    
    constructor(private httpService: HttpService){}
     
    ngOnInit(){
         
        this.httpService.getUsers().subscribe(data => this.users=data);
    }
}

НазадВперед

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector