Effects¶
NgRx Effects реализуют побочные эффекты, работающие на основе библиотеки RxJS, применительно к хранилищу. Отслеживая поток действий, отправляемых в Store
, они могут генерировать новые действия, например, на основе результатов выполнения HTTP-запросов или сообщений, полученных через Web Sockets.
Цели и функции NgRx Effects:
- снять нагрузку с компонента по управлению состоянием и выполнению побочных эффектов и свести его работу к получению состояний и генерации действий;
- отслеживание и фильтрация потока действий для выполнения побочного эффекта при возникновении определенного действия;
- выполнение синхронных и асинхронных побочных эффектов.
NgRx Effects устанавливаются отдельно.
1 |
|
Чтобы полностью осознать все преимущества использования NgRx Effects, посмотрим на пример без них.
articles.service.ts
1 2 3 4 5 6 7 8 |
|
articles.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
А теперь изменим пример внедрением NgRx Effects (ArtilcesService
остается неизменным).
articles.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
articles.actions.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
articles.reducer.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
articles.effects.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
app.module.ts
1 2 3 4 |
|
Создание NgRx Effect начинается c отслеживания потока событий, который представлен сервисом Actions
и предваряется декоратором @Effect()
. Далее с помощью оператор ofType()
задается тип действия, при возникновении которого будет выполнен побочный эффект, который в свою очередь должен возвращать новое действие, передаваемое далее в хранилище. Также не забывайте обрабатывать ошибки.
Сначала действие обрабатывается редюсером, а только потом попадает в поток сервиса Actions
.
Сравнив два примера, сразу станет очевидно, что применение NgRx Effects избавило компонент от необходимости самостоятельно обращаться к сервису и контролировать результат его работы.
Все NgRx Effects должны регистрироваться в приложении с помощью модуля EffectsModule
. Если вы определяете эффекты на уровне корневого модуля, то необходимо использовать метод forRoot()
, если на уровне второстепенного — forFeature()
. Оба метода принимают массив эффектов к качестве параметра.
Если в приложении все NgRx Effects определены для второстепенных модулей, то в корневом модуле обязательно должен быть импортирован без аргументов метод EffectsModule.forRoot()
.
Эффекты начинают следить за потоком действий сразу после загрузки модуля, к которому они относятся.
Если вам необходимо реализовать побочный эффект, но новое действие генерировать не нужно, передайте декоратору @Effect()
объект с указанием значения false
для свойства dispatch
.
В случае задания {dispatch: false}
, действие, инициирующее выполнение эффекта, никогда не будет передано редюсеру.
1 |
|
Жизненный цикл NgRx Effects¶
После регистрации всех эффектов в корневом модуле, происходит генерация действия ROOT_EFFECTS_INIT
, для обработки которого может быть создан отдельный NgRx Effects.
1 2 3 4 5 |
|
NgRx предоставляет возможность управлять жизненным циклом эффекта с помощью реализации интерфейсов:
OnInitEffects
— возвращает действие сразу после того, как эффект был зарегистрирован в приложении;OnRunEffects
— позволяет управлять началом и окончанием работы эффекта (по умолчанию начинается и заканчивается вместе с работой приложения);OnIdentifyEffects
— позволяет регистрировать NgRx Effects несколько раз (по умолчанию эффект регистрируется в Angular приложении один раз, независимо от того, сколько раз загружается сам класс эффекта).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
|
Здесь для демонстрации работы OnInitEffects
и OnRunEffects
было введено дополнительное действие ArticlesEffectsInit
, которое генерируется в момент регистрации эффекта и тем самым инициирует отслеживание потока действий.
В пределах одного класса может быть реализовано сразу несколько эффектов.
1 2 3 4 5 6 7 8 |
|