Привіт усім!
Нещодавно я переглядав свої старі нотатки і натрапив на корисний декоратор, який я створив для проєктів на Angular. Він називається TakeUntilDestroy і допомагає керувати очищенням обсерваблів, автоматично відписуючись від них, коли компонент знищується. Я подумав поділитися цим з вами, оскільки це може бути корисним для когось, хто стикається з подібними викликами. Давайте розберемося!
Що таке TakeUntilDestroy?
У Angular керування підписками на обсерваблі може бути важким, особливо забезпечення їх належної відписки, коли компонент знищується. Невдача в цьому може призвести до витоків пам'яті та несподіваної поведінки. Декоратор TakeUntilDestroy забезпечує зручний спосіб впоратися з цим, автоматично відписуючись від обсерваблів.
Створення декоратора takeUntilDestroy
Спочатку давайте визначимо декоратор takeUntilDestroy
. Цей декоратор додасть властивість takeUntil
до вашого компонента, надаючи методи для автоматичного керування очищенням підписки.
Ось код для декоратора takeUntilDestroy
:
import { Subject, MonoTypeOperatorFunction } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
export interface ITakeUntilDestroy {
destroyComponent: <T>() => MonoTypeOperatorFunction<T>;
unsubscribeAll: () => void;
}
export interface ITakeUntilDestroyDecorator {
unsubscribe$?: Subject<void>;
takeUntil: ITakeUntilDestroy;
}
export function TakeUntilDestroy() {
return function <T extends { new(…args: any[]): {} }>(constructor: T) {
constructor.prototype.takeUntil = {
unsubscribe$: new Subject<void>(),
destroyComponent: function <T>(): MonoTypeOperatorFunction<T> {
return takeUntil(this.unsubscribe$);
},
unsubscribeAll: function () {
if (this.unsubscribe$) {
this.unsubscribe$.next();
this.unsubscribe$.complete();
this.unsubscribe$.unsubscribe();
}
}
};
constructor.prototype.ngOnDestroy = function () {
this.takeUntil.unsubscribeAll();
};
};
}
Використання декоратора takeUntilDestroy
Тепер, коли у нас є наш декоратор, давайте подивимося, як його використовувати в компоненті Angular. Декоратор takeUntilDestroy застосовується до класу компонентів для автоматичного керування очищенням підписок.
Ось приклад компонента, який використовує декоратор takeUntilDestroy
:
import { Component, OnInit } from '@angular/core';
import { inject } from '@angular/core';
import { SomeService } from './some.service';
import { TakeUntilDestroy, ITakeUntilDestroy } from './take-until-destroy.decorator';
@TakeUntilDestroy()
@Component({
selector: 'app-example',
standalone: true,
template: ``
})
export class AppExample implements OnInit {
public takeUntil!: ITakeUntilDestroy;
private readonly someService = inject(SomeService);
public ngOnInit() {
this.someService.someStream$.pipe(this.takeUntil.destroyComponent()).subscribe(() => {
// Handle the stream data
});
}
// Optional: if you need your own way to unsubscribe all observables
public ownDestroyMethod() {
this.takeUntil.unsubscribeAll();
}
}
Як це працює
Налаштування декоратора: Декоратор
TakeUntilDestroy
покращує клас компонента, додаючи властивістьtakeUntil
. Ця властивість міститьSubject
, який використовується для сигналізації про те, коли слід очистити підписки, та методи для керування процесом відписки.Ініціалізація компонента: У життєвому циклі компонента
ngOnInit
ви можете використовувати методdestroyComponent
, наданий властивістюtakeUntil
, для керування вашими підписками. Цей метод використовує операторtakeUntil
з RxJS, який завершить обсервабль, коли компонент знищується.Знищення компонента: Коли компонент знищується (через
ngOnDestroy
), викликається методunsubscribeAll
, який випускає значення до темиunsubscribe$
, змушуючи всі обсерваблі, які були використані черезdestroyComponent
, завершитися, тим самим очищаючи підписки.
Висновок Використання декоратора takeUntilDestroy
є потужним способом керування підписками в компонентах Angular, забезпечуючи їх належне очищення та запобігання витокам пам'яті. Слідуючи викладеним вище крокам, ви легко можете інтегрувати цей шаблон у ваші додатки Angular.
Дякую, що знайшли час прочитати цей допис. Сподіваюся, ви вважаєте його корисним та інформативним. Якщо у вас є будь-які питання або зауваження, будь ласка, залиште коментар.