Связь между Angular компонентами с помощью RxJS
В этой статье я буду использовать RxJS, чтобы показать, как компоненты взаимодействуют, когда они не знают друг друга или не имеют общих родительских / дочерних отношений.
Проблема
Во многих интерфейсных средах, включая Angular, всегда возникает проблема связи, когда мы делим наше приложение или страницу на множество небольших компонентов пользовательского интерфейса и привязываем события к родительскому элементу родительского элемента компонента-прародителя, чтобы узнать, что происходит.
В Angular мы используем @Input()
и @Output()
. В обычных случаях это работает хорошо, но когда мы хотим связать входящие данные и события, с глубоко вложенным компонентом и верхнеуровневым контейнером, управление подобной структурой может легко превратиться в кошмар.
Нам нужно добавить у каждого потомка @Input()
и @Output()
, это требует больших усилий и сопряжено с риском что при передачи данные будут изменены.
Одним из решений является использование управления состоянием, такого как Redux, NGRX или NGXS, чтобы помочь компонентам, которые не подключены, обмениваться данными.
В этой статье я представлю два дополнительных решения для решения этой проблемы без необходимости введения библиотеки управления состоянием в ваш код.
- Event Bus с помощью
Subject
. - Observable сервис с
Behavior Subject
.
Чтобы продемонстрировать это решение, я создам пример исходного кода, который позволяет пользователю щелкнуть элемент списка статей и отобразить подробности в другом компоненте.
Решение Event Bus
Концепция Event Bus очень проста. Вы создадите сервис автобусов для мероприятий, который будет доступен по всему миру.
Затем вы можете отправить событие на шину, и если какой-либо слушатель был зарегистрирован на это имя события, он выполнит функцию обратного вызова.
В этой статье я создам шину событий, используя RsJS Subject.
Из списка статей каждый раз, когда пользователь нажимает на элемент, он генерирует одно событие и передает данные статьи в шину событий.
Этот код означает, что мы отправляем событие SelectArticleDetail
вместе с информацией о статье.
Теперь в компоненте detail будет прослушиваться это событие.
Подписчик будет прослушивать SelectArticleDetail
и выполнять необходимые действия назначая данные статьи локальной переменной и отображая их в пользовательском интерфейсе.
Решение с использование BehaviorSubject
Эта идея просто состоит в том, чтобы создать инвентарь для передачи значений внутри. Таким образом, каждый раз, когда изменяется инвентарь, наблюдатель узнает об этом и выполнит необходимые действия.
Мы создаем BehaviorSubject
с именем товара по умолчанию inventorySubject$
и методом addToInventory()
для добавления товара в инвентарь.
Из списка статей каждый раз, когда пользователь нажимает на товар, он добавляет товар в инвентарь.
Теперь, в компоненте с детальной информацией, мы подпишемся на инвентарь, чтобы получить новое значение.
Тематические исследования
Я применил эти методы ко многим проектам, и вот несколько реальных случаев, которые я нашел полезными:
- Шина событий: я хочу сгруппировать один и тот же модал или всплывающее окно, чтобы информировать пользователя о состоянии веб-приложения каждый раз, когда пользователь взаимодействует с API с помощью кнопки на пользовательском интерфейсе.
- Шина событий: В случае моно репо с разными платформами внешнего интерфейса я использую шину событий для отправки событий и прослушивания между различными платформами или отправки из Angular и прослушивания Vanilla Javascript.
- Шина событий и служба Observable для вложенных компонентов: это сложно, когда мы используем
@Input()
и@Output()
когда хотим связать данные или события, входящие и выходящие из компонента D (компонент пользовательского интерфейса) в C (компонент пользовательского интерфейса), в B (компонент пользовательского интерфейса) и в А (Контейнерный компонент) для связи с API.
Резюме
Подводя итог, эта статья представляет два способа связи между двумя или более компонентами, которые не знают друг о друге.
Мы используем Observable, чтобы подписаться на данные для простых случаев, и используем шину событий, чтобы отправлять разные имена событий разным слушателям.
Перевод статьи: Communicate Between Angular Components Using RxJS
Источник: levelup.gitconnected.com