Продовжуючи вивчення сигналів з Практичного посібника по сигналам — Частина I, я підготував для вас потужну практичну демонстрацію.
Міграція сервісів на основі BehaviorSubject до нового API Signals
Я впевнений, що ви бачили багато статей, де створюється лічильник для демонстрації сигналів, і тепер ви, мабуть, думаєте:
Ще одна демонстрація з лічильником?
Традиційно розробники використовували BehaviorSubject з RxJS для управління реактивними станами в сервісах. Хоча цей підхід був досить зручним, введення Signals в Angular надає новий, інтуїтивно зрозумілий і легший спосіб керувати реактивністю станів.
У цій демонстрації ми пройдемо через процес міграції сервісу Angular, який використовує BehaviorSubject, до нового Signals API.
До кінця цієї міграції ви будете почуватися більш впевнено при міграції сервісів у вашому проєкті, що залежать від BehaviorSubject, до нового Signals API, а також побачите, як Signals покращують управління станом з простішим синтаксисом та декларативною реактивністю, роблячи ваш код чистішим і більш підтримуваним.
Приклад, який ми розглянемо, це застосунок, що перемикає стан завантаження на основі відповіді від хмарної функції.
Сервіс на основі RxJS виглядає так:
import { Injectable } from "@angular/core";
import { BehaviorSubject } from "rxjs";
@Injectable({
providedIn: "root",
})
export class LoaderService {
private loader = new BehaviorSubject(false);
loader$ = this.loader.asObservable();
switchLoader = (value: boolean) => this.loader.next(value);
}
На основі відповіді від нашої хмарної функції / API ми перемикаємо лоадер:
this.loaderService.switchLoader(true);
Нарешті, ви підписуєтесь на обсервабель loader$
у вашому компоненті або використовуєте пайп async
у шаблоні.
loading = false;
destroy$: Subject = new Subject();
this.loaderService.loader$
.pipe(takeUntil(this.destroy$))
.subscribe((isLoading) => {
this.loading = isLoading;
});
Досить багато шаблонного коду, правда?
Тепер давайте мігруємо сервіс лоадера до нового API на основі сигналів.
import { Injectable, signal } from "@angular/core";
@Injectable({
providedIn: "root",
})
export class LoaderService {
private loader = signal(false);
loaderSignal = this.loader.asReadonly();
switchLoader = (value: boolean) => {
this.loader.update((currentLoadingState) => (currentLoadingState = value));
};
}
Тепер просто використовуйте це в шаблоні як loaderService.loaderSignal()
або зв’яжіть змінну сигналу з вашим компонентом, а потім використовуйте її в шаблоні як loader()
.
private loaderService = inject(LoaderService);
loading = this.loaderService.loaderSignal;
Такий підхід можна реалізувати для будь-якого сервісу на основі BehaviorSubject, незалежно від того, наскільки складні об'єкти у вас є.
Спробуйте це на практиці.
Сподобалося те, що ви дізналися? Підтримайте цей матеріал аплодисментами 👏
Перекладено з: A Pragmatic Guide To Signals — Part II (demo time)