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 | |