2016-12-14 12 views
15

Znajduję wiele przykładów, w których ActivatedRoute Obserwowalne, takie jak params lub url są subskrybowane, ale nie są anulowane.Czy muszę anulować subskrypcję obserwowanych obiektów ActivatedRoute (np. Params)?

constructor(private route: ActivatedRoute) {} 

ngOnInit() { 
    this.route.params 
    // (+) converts string 'id' to a number 
    .switchMap((params: Params) => this.service.getHero(+params['id'])) 
    .subscribe((hero: Hero) => this.hero = hero); 
} 
  • są obiekty tras i subskrypcje zniszczone automagicznie i nowo tworzone dla każdego stworzenia komponentu?
  • Czy muszę zadbać o anulowanie subskrypcji z tych Observable s?
  • Jeśli nie, to czy możesz wyjaśnić, co dzieje się z drzewem obiektów ActivatedRoute w Router. routerState?

Odpowiedz

20

From the docs:

Kiedy zapisanie się zauważalny w komponencie, prawie zawsze zorganizować zrezygnować, gdy składnik jest zniszczona.

Istnieje kilka wyjątkowych obserwowalnych miejsc, w których nie jest to konieczne. Obserwacje ActivatedRoute należą do wyjątków.

AktywowanyRoute i jego obserwowalne są izolowane od samego routera. Router niszczy przekierowany komponent, gdy nie jest już potrzebny, a wstrzyknięty ActivatedRoute umiera wraz z nim.

W każdym razie możesz zrezygnować z subskrypcji. Jest nieszkodliwa i nigdy nie jest złą praktyką.

+1

Jak zrezygnować z subskrypcji, ponieważ jest to "nigdy nie jest zła praktyka". Dokumenty nie podają przykłady w ogóle wypisywanie – TetraDev

+4

@TetraDev tak .. ngOnInit() { this.routeSub = this.route.paramMap .subscribe (params => { this.event = this.eventService.getEvent (+ params.get ('id')); }); } ngOnDestroy() { this.routeSub.unsubscribe(); } – DJDJ

+0

Dzięki @DJDJ. dobra wskazówka – TetraDev

5

Komponent zostanie zniszczony, a stan routera stanie się bez odniesienia, gdy router przejdzie na inną trasę, co spowoduje, że będą mogli swobodnie gromadzić śmieci, w tym obserwowalne.

Jeśli przekażesz odniesienia do tego komponentu innym komponentom lub usługom, komponent nie zostanie zbufowany i subskrypcja pozostanie aktywna, ale jestem pewien (bez weryfikacji), że obserwowalny zostanie zakończony przez routera podczas nawigacji i powodują anulowanie subskrypcji.

+0

Oznacza to, że 'ActivatedRoute' jest nowa instancja każdej nawigacji po trasie, prawda? W jaki sposób działałaby subskrypcja zmienionych parametrów trasy? Może mógłbyś wyjaśnić specjalny cykl życia "ActivatedRoute"? Czy drzewo "RouterState" jest odtwarzane z katalogu głównego po każdej nawigacji? Jeśli komponent zostanie zniszczony po nawigacji, spowoduje to migotanie !? – hgoebl

+1

Po przejściu do innej trasy, komponent zostanie zniszczony, po przywróceniu zostanie odtworzony. Jeśli masz ten sam komponent na różnych trasach i przechodzisz od jednego do drugiego, komponent jest również niszczony i odtwarzany. Tylko podczas nawigacji, tak że zmieniają się tylko parametry trasy, instancja składnika jest ponownie wykorzystywana. Najnowsze wersje obsługują niestandardową strategię ponownego wykorzystania. Zobacz także https://github.com/angular/angular/issues/7757#issuecomment-236737846 i https: //www.softwarearchitekt.w/post/2016/12/02/sticky-routes-in-angle-2-3-with-routereusestrategy.aspx –

+0

Dziękuję Zöchi za odpowiedź. Nie byłem pewien, kto dostanie nagrodę, ale Milad ma tylko 1 punkt reputacji, a Ty masz już 149 000. BTW jego odpowiedź dowodzi, powołując się na oficjalnych dokumentów. Następnym razem, wkrótce, znowu będziesz człowiekiem :-) – hgoebl

0

Jako wygrywająca odpowiedź automatycznie otrzymuje się quotes o subscriptions na ActivatedRoute, Angular unsubscribes.

The Router destroys a routed component when it is no longer needed and the injected ActivatedRoute dies with it.

W przypadku, gdy chcesz wiedzieć, jak unsubscribe z Observables:

import { Component, 
     OnInit, 
     OnDestroy }  from '@angular/core'; 
import { ActivatedRoute } from '@angular/router'; 
// Type 
import { Subscription } from 'rxjs/Subscription'; 


@Component({ 
    selector: 'app-example', 
    templateUrl: './example.component.html', 
    styleUrls: ['./example.component.scss'] 
}) 
export class ExampleComponent implements OnInit, OnDestroy { 
    paramsSubscription : Subscription; 

    constructor(private activatedRoute : ActivatedRoute) { } 

    /* Angular lifecycle hooks 
    */ 
    ngOnInit() { 
    console.log("Component initialized"); 
    this.paramsSubscription = activatedRoute.params.subscribe(params => { 

    }); 
    } 

    ngOnDestroy() { 
    console.log("Component will be destroyed"); 
    this.paramsSubscription.unsubscribe(); 
    } 

}