Muss ich mich von ActivatedRoute (z. B. params) Observables abmelden?


77

Ich finde viele Beispiele , in denen ActivatedRouteObservable wie paramsoder urlabonniert haben , aber nicht abgemeldet.

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);
}
  • Werden die Routenobjekte und Abonnements automatisch zerstört und bei jeder Komponentenerstellung neu erstellt?
  • Muss ich mich darum kümmern, mich von diesen Observableabzumelden?
  • Wenn nicht, können Sie erklären, was mit dem Baum der ActivatedRoute-Objekte in passiert Router. routerState?

Sie müssen keine Router-Parameter abbestellen. Sie müssen sich nur abmelden, wenn Sie auf Komponentenebene erstellt haben.
kk4You

Antworten:


160

Aus den Dokumenten :

Wenn Sie ein Observable in einer Komponente abonnieren, können Sie sich fast immer abmelden, wenn die Komponente zerstört wird.

Es gibt einige außergewöhnliche Observable, bei denen dies nicht erforderlich ist. Die ActivatedRoute-Observablen gehören zu den Ausnahmen.

Die ActivatedRoute und ihre Observablen sind vom Router selbst isoliert. Der Router zerstört eine geroutete Komponente, wenn sie nicht mehr benötigt wird, und die injizierte ActivatedRoute stirbt damit.

Fühlen Sie sich trotzdem frei, sich abzumelden. Es ist harmlos und niemals eine schlechte Praxis.


4
Wie können Sie sich abmelden, da dies "niemals eine schlechte Praxis" ist? Docs geben überhaupt keine Beispiele für das Abbestellen
TetraDev

8
@TetraDev Gefällt mir .. ngOnInit () {this.routeSub = this.route.paramMap .subscribe (params => {this.event = this.eventService.getEvent (+ params.get ('id'));}); } ngOnDestroy () {this.routeSub.unsubscribe (); }
DJDJ

wie wollen Sie , unsubscribewenn Sie melden sich ActivatedRoutein app.component?
CandidJ

@candidJ Sie können sich auf die gleiche Weise wie @DJDJ abmelden, aber da app.componentes so lange lebt, wie die App lebt, besteht dort ohnehin keine wirkliche Notwendigkeit, sich abzumelden.
Crollywood

1
Ich habe den Dokumentationslink in dieser Antwort aktualisiert, aber beachten Sie, dass "Sie können sich trotzdem abmelden. Es ist harmlos und niemals eine schlechte Praxis." Satz ist nicht mehr in der Dokumentation.
Sébastien

7

Die Komponente wird zerstört und der RouterState wird nicht mehr referenziert, wenn der Router zu einer anderen Route navigiert. Dadurch können sie den Müll einschließlich der beobachtbaren Daten sammeln.

Wenn Sie Verweise auf diese Komponente an andere Komponenten oder Dienste weitergeben, wird die Komponente nicht durch Müll gesammelt und das Abonnement bleibt aktiv, aber ich bin sicher (ohne zu überprüfen), dass das Observable beim Navigieren vom Router vervollständigt wird weg und veranlassen, dass das Abonnement kündigt.


1
Das heißt, das ActivatedRouteist nach jeder Routennavigation eine neue Instanz, oder? Wie würde dann das Abonnement für geänderte Routenparameter funktionieren? Vielleicht könnten Sie den besonderen Lebenszyklus von erklären ActivatedRoute? Wird der RouterStateBaum nach jeder Navigation aus der Wurzel neu erstellt? Wenn die Komponente nach der Navigation zerstört wird, kann dies zu Flackern führen!?
Hgoebl

2
Wenn Sie zu einer anderen Route navigieren, wird die Komponente zerstört. Wenn Sie zurück navigieren, wird sie neu erstellt. Wenn Sie dieselbe Komponente auf verschiedenen Routen haben und von einer zur anderen navigieren, wird die Komponente ebenfalls zerstört und neu erstellt. Nur wenn Sie navigieren, sodass sich nur die Routenparameter ändern, wird die Komponenteninstanz wiederverwendet. Neuere Versionen unterstützen eine benutzerdefinierte Wiederverwendungsstrategie. Siehe auch github.com/angular/angular/issues/7757#issuecomment-236737846 und softwarearchitekt.at/post/2016/12/02/…
Günter Zöchbauer

Danke Zöchi für deine Antwort. Ich war mir nicht sicher, wer das Kopfgeld bekommen wird, aber Milad hat nur 1 Punkt Ruf, während Sie bereits 149.000 haben. Übrigens beweist seine Antwort unter Berufung auf offizielle Dokumente. Das nächste Mal, sehr bald, wirst du wieder der Mann sein :-)
hgoebl

Keine Sorgen. Frohes neues Jahr :)
Günter Zöchbauer

6

Da der Gewinn Antwort Zitate über das subscriptionszu ActivatedRoute, Angular unsubscribesautomatisch.

Der Router zerstört eine geroutete Komponente, wenn sie nicht mehr benötigt wird, und die injizierte ActivatedRoute stirbt damit.

Falls Sie wissen , wie man unsubscribeaus 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 = this.activatedRoute.params.subscribe( params => {

    });
  }

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

}

1

Wenn Sie eine Komponente abonnieren, müssen Sie sich fast immer abmelden, wenn die Komponente zerstört wird. Das Abonnieren der aktivierten Routenparameter erfordert jedoch kein Abbestellen, da der Router das Abonnement zerstört, wenn es nicht mehr benötigt wird.


0

HTTP-Observables-Anrufe und Router-Observables müssen nicht manuell abbestellt werden. Wenn Sie mit einer anderen Art von Observable oder Ihrer eigenen Observable umgehen, sollten Sie dies auf ngOnDestroy () tun. Sie rufen dazu die Methode unsubscribe () im Suscription-Objekt auf, in dem Sie Ihre Observable in der Komponente speichern.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.