Wróć do strony głównej
Angular

Poznaj DestroyRef!

DestroyRef został wprowadzony w Angular 16 (commit link) i daje nam możliwość uruchomienia callback’a, gdy komponent/dyrektywa lub powiązany injector zostanie zniszczony.

Zobaczmy prosty przykład, aby zrozumieć, jak możemy tego użyć.

Callback, gdy komponent jest niszczony

Powyższy kod emituje nową wartość co 1 sekundę (1000 ms) i wyrzuca ją do konsoli. Ten niewielki fragment kodu nadal powoduje wyciek pamięci, ponieważ nie niszczymy subskrypcji. 

Odpowiedzmy na kilka pytań

P: Co się stanie, jeśli znawigujemy się do innego route’a? 

O: Cóż, komponent zostanie zniszczony.

 

P: Co by się stało, gdybyśmy wrócili na tę trasę

O: Cóż, komponent zostanie skonstruowany ponownie. 

Pomimo zniszczenia komponentu, subskrypcja pozostaje aktywna. 

Musimy anulować subskrypcję, aby uniknąć wycieku pamięci. Ale prawdopodobnie już o tym wiesz i stosujesz się do tego w praktyce ?
Zróbmy teraz to samo, ale tym razem używając </span><b>DestroyRef zamiast hook’a OnDestroy 

Przejdźmy przez ten kod po kolei: 

  • Tworzymy instancję #destroyRef przy użyciu metody </span><b>inject (należy pamiętać, że może to robić tylko wewnątrz tzw. injection context). 
  • Rejestrujemy callback w metodzie </span><b>onDestroy. Podana funkcja zostanie  wykonana, gdy komponent zostanie zniszczony. 

Alternatywnie, moglibyśmy napisać to w ten sposób: 

Zauważ, że tym razem używamy funkcji </span><b>inject w konstruktorze. To nadal działa dobrze,  ponieważ ciało konstruktora zawiera się również w injection context’cie. 

Istnieje jednak lepszy sposób na zamknięcie subskrybcji, bądź cierpliwa/y! 🙂 

TakeUntilDestroyed

Zanim przejdziemy do tego lepszego sposobu, zaimplementujmy customową metodę </span><span style="font-weight: 400;">myTakeUntilDestroyed.

Stworzyłem metodę myTakeUntilDestroyed, która wstrzykuje DestroyRef. Ważne jest, aby zrozumieć, że nie możemy użyć metody inject poza injection context’em. W powyższym przykładzie wywołuję myTakeUntilDestroyed z konstruktora, co działa poprawnie.

Injection Context: Konstruktor, pola klasy, factory function -> Czytaj więcej

Co by się stało, gdybyśmy wywołali metodę z hook’a </span><span style="font-weight: 400;">ngOnInit? 

Ponieważ nie jesteśmy w injection context’cie, Angular zgłosi błąd.

Jeśli chcielibyśmy wywołać </span><span style="font-weight: 400;">myTakeUntilDestroyed z hook’a </span><span style="font-weight: 400;">ngOnInit, powinniśmy zmienić sposób dostępu do </span><span style="font-weight: 400;">DestroyRef

Zmiana ta pozwala na użycie </span><span style="font-weight: 400;">myTakeUntilDestroyed poza kontekstem  wstrzykiwania, np, w hook’u OnInit.

Bazując na tym czego dowiedzieliśmy się implementując metodę </span><span style="font-weight: 400;">myTakeUntilDestroyed , możemy przejść do docelowego rozwiązania, tj. rxjs’owego operatora </span><span style="font-weight: 400;">takeUntilDestroyed.

takeUntilDestroyed  kończy subskrybcję, gdy komponent/dyrektywa zostanie zniszczona lub gdy przekazany do niej injector zostanie zniszczony. 

Osiągnęliśmy to samo z czytelniejszym kodem i wykorzystaniem istniejącego operatora. Ale co jeśli chcemy go użyć w hook’u </span><span style="font-weight: 400;">ngOnInit

Jeśli musimy użyć operatora takeUntilDestroyed poza injection context’em, my (programiści) jesteśmy odpowiedzialni za dostarczenie </span><span style="font-weight: 400;">DestroyRef jako parametru, analogiczniej jak w naszej customowej metodzie myTakeUntilDestroyed.

Jeśli lubisz oglądać filmy, koniecznie obejrzyj ten, który obejmuje przydatne informacje o DestroyRef > Obejrzyj teraz

Przydatne linki: 

Dzięki za przeczytanie mojego artykułu!

O autorze

Fanis Prodromou

Jestem full-stack web developerem z pasją do Angulara i NodeJs. Mieszkam w Atenach-Grecji i pracowałem w wielu dużych firmach. Podczas moich 14 lat kodowania zdobyłem ogromne doświadczenie w zakresie jakości kodu, architektury aplikacji oraz ich wydajności.

Zdając sobie sprawę z tego, jak szybko rozwija się informatyka i aspekty techniczne, staram się być na bieżąco, uczestnicząc w konferencjach i meetupach, studiując i próbując nowych technologii. Uwielbiam dzielić się swoją wiedzą i pomagać innym programistom.

“Sharing is Caring”

Uczę Angulara w firmach korporacyjnych poprzez instytut Code.Hub, piszę artykuły i tworzę filmy na YouTube.

Zapisz się do naszego newslettera. Bądź na bieżąco z najnowszymi trendami, poradami, meetupami i stań się częścią społeczności Angulara w Polsce. Rynek pracy docenia członków społeczności.

Leave a Reply

Your email address will not be published. Required fields are marked *