Angulaire 4+ ngOnDestroy() dans le service de détruire observables
dans une application angulaire, nous avons le crochet de cycle de vie ngOnDestroy()
pour un composant / directive et nous utilisons ce crochet pour désabonner les observables.
je veux effacer / détruire observable qui sont créés dans un service @injectable()
.
J'ai vu quelques posts disant que ngOnDestroy()
peut être utilisé dans un service.
Mais, est-ce une bonne pratique et la seule façon de le faire et Quand doit-il être appelé ? que quelqu'un clarifie.
4 réponses
OnDestroy lifecycle hook est disponible chez les fournisseurs. Selon les documents:
crochet du cycle de vie qui s'appelle lorsqu'une directive, un tuyau ou un service est détruit.
voici un exemple :
@Injectable()
class Service implements OnDestroy {
ngOnDestroy() {
console.log('Service destroy')
}
}
@Component({
selector: 'foo',
template: `foo`,
providers: [Service]
})
export class Foo {
constructor(service: Service) {}
ngOnDestroy() {
console.log('foo destroy')
}
}
@Component({
selector: 'my-app',
template: `<foo *ngIf="isFoo"></foo>`,
})
export class App {
isFoo = true;
constructor() {
setTimeout(() => {
this.isFoo = false;
}, 1000)
}
}
notez que dans le code ci-dessus Service
est une instance qui appartient au composant Foo
, donc il peut être détruit quand Foo
est détruit.
pour les fournisseurs qui appartiennent à root injector cela se produira sur application destroy, ceci est utile pour éviter les fuites de mémoire avec plusieurs bootstraps, c.-à-d. dans les tests.
Lorsqu'un fournisseur de services de parent injecteur est abonné à la composante enfant, il ne sera pas détruit sur la composante détruire, c'est la responsabilité de la composante de se désabonner dans la composante ngOnDestroy
(comme une autre réponse explique).
créer une variable à votre service
subscriptions: Subscriptions[]=[];
poussez chacun de votre abonnement au tableau comme
this.subscriptions.push(...)
Écrire un dispose()
méthode
dispose(){
this.subscriptions.forEach(subscription =>subscription.unsubscribe())
appelez cette méthode de votre composant pendant ngOnDestroy
ngOnDestroy(){
this.service.dispose();
}
Juste pour clarifier - vous n'avez pas besoin de détruire Observables
mais seuls les abonnements.
il semble comme d'autres ont souligné que vous êtes maintenant en mesure d'utiliser ngOnDestroy
avec les services ainsi. Lien: https://angular.io/api/core/OnDestroy
je préfère Ce modèle takeUntil(onDestroy$)
activé par des opérateurs pipables. J'aime que ce modèle soit plus concis, plus propre, et qu'il exprime clairement l'intention de tuer un abonnement lors de l'exécution du crochet de cycle de vie OnDestroy
.
Ce modèle fonctionne aussi bien pour les services que pour les composants souscrivant à des observables injectés. Le code squelette ci-dessous devrait vous donner assez de détails pour intégrer le modèle dans votre propre service. Imaginez que vous importez un service appelé InjectedService
...
import { InjectedService } from 'where/it/lives';
import { Injectable, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MyService implements OnDestroy {
private onDestroy$ = new Subject<boolean>();
constructor(
private injectedService: InjectedService
) {
// Subscribe to service, and automatically unsubscribe upon `ngOnDestroy`
this.injectedService.observableThing().pipe(
takeUntil(this.onDestroy$)
).subscribe(latestTask => {
if (latestTask) {
this.initializeDraftAllocations();
}
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
le sujet de quand/comment se désabonner est traité en détail ici: Angular/RxJS Quand dois-je me désabonner de `Abonnement '