Angulaire/RxJs Quand dois-je me désinscrire "Abonnement"
Quand dois-je stocker les Subscription
instances et invoquer unsubscribe()
au cours de la NgOnDestroy cycle de vie et quand puis-je tout simplement les ignorer?
De la sauvegarde de tous les abonnements introduit beaucoup de gâchis dans le code du composant.
HTTP le Guide du Client ignorer les abonnements comme ceci:
getHeroes() {
this.heroService.getHeroes()
.subscribe(
heroes => this.heroes = heroes,
error => this.errorMessage = <any>error);
}
Dans le même temps Itinéraire & Guide de Navigation dit que:
Finalement, nous allons naviguer ailleurs. Le routeur va supprimer cette composante dans les DOM et les détruire. Nous devons nettoyer derrière nous avant que cela arrive. Plus précisément, nous nous devons de vous désabonner avant Angulaire détruit le composant. Ne pas le faire pourrait créer une fuite de mémoire.
Nous vous désinscrire de notre
Observable
dans lengOnDestroy
méthode.
private sub: any;
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
let id = +params['id']; //(+) converts string 'id' to a number
this.service.getHero(id).then(hero => this.hero = hero);
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
- Je suppose que
Subscription
s àhttp-requests
peut être ignoré, car elle ne fait appelonNext
une fois et puis ils appellentonComplete
. LeRouter
au lieu des appelsonNext
à plusieurs reprises, et pourraient ne jamais l'appeleronComplete
(pas sûr...). En va de même pourObservable
s deEvent
s. Donc je suppose que ceux-ci devraient êtreunsubscribed
. - Le flux est terminée (ou ne pas remplir), indépendamment de toute observation de la réalisation. Les rappels (l'observateur) fourni à la souscription de la fonction ne permettent pas de déterminer si les ressources sont allouées. C'est l'appel à
subscribe
lui-même qui, potentiellement, de l'allocation des ressources en amont.
Vous devez vous connecter pour publier un commentaire.
--- Edition 4 - Des Ressources Supplémentaires (2018/09/01)
Dans un récent épisode de Aventures dans Angulaire Ben Lesh et de la Paroisse de Bell examiner les questions autour de comment/quand vous désabonner en un composant. La discussion commence à 1:05:30.
Paroisse mentionne
right now there's an awful takeUntil dance that takes a lot of machinery
et Shai Reznik mentionneAngular handles some of the subscriptions like http and routing
.En réponse Ben mentionne qu'il y a des discussions en ce moment pour permettre à des Observables pour accrocher dans l'angle de la composante du cycle de vie des événements et de la Paroisse suggère une Observable des événements du cycle de vie d'un composant peut s'abonner à un moyen de savoir quand terminer Observables maintenu en tant que composante interne de l'état.
Cela dit, nous avons surtout besoin de solutions maintenant donc, voici quelques autres ressources.
Une recommandation pour la
takeUntil()
modèle de RxJs membre de l'équipe noyau Nicolas Jamieson et un tslint règle pour l'aider à la faire respecter. https://blog.angularindepth.com/rxjs-avoiding-takeuntil-leaks-fb5182d047efLéger mnp package qui expose une Observable de l'opérateur qui prend une instance de composant (
this
) en tant que paramètre et se désinscrit automatiquement lors dengOnDestroy
.https://github.com/NetanelBasal/ngx-take-until-destroy
Une autre variation de la ci-dessus avec un peu meilleure ergonomie, si vous ne faites AOT versions (mais nous devrions tous faire de AOT maintenant).
https://github.com/smnbbrv/ngx-rx-collector
Personnalisé directive
*ngSubscribe
qui fonctionne comme async pipe, mais crée une vue intégrée dans votre modèle de sorte que vous pouvez vous référer à la "déballé" valeur tout au long de votre modèle.https://netbasal.com/diy-subscription-handling-directive-in-angular-c8f6e762697f
Je le mentionne dans un commentaire à Nicolas blog que la sur-utilisation de
takeUntil()
pourrait être un signe que votre composant est d'essayer d'en faire trop et que la séparation de vos composants existants dans Fonction et de Présentation composants doivent être considérés. Vous pouvez ensuite| async
Observables à partir de la Fonctionnalité du composant dans unInput
de la Présentation du composant, ce qui signifie aucun abonnement n'est nécessaire, n'importe où. Lire plus sur cette approche ici--- Edition 3 - Le "Officielle" De La Solution (2017/04/09)
J'ai parlé avec de la Paroisse de Bell à propos de cette question à NGConf (j'ai même lui a montré cette réponse qu'il a dit est correct) mais il m'a dit à l'équipe docs Angulaire a une solution à cette question qui est inédit (bien qu'ils travaillent sur l'obtenir approuvé). Il m'a aussi dit que je pouvais mettre à jour mon DONC réponse à la recommandation officielle.
La solution que nous devrions tous utiliser à l'avenir est d'ajouter un
private ngUnsubscribe = new Subject();
champ à tous les composants qui ont.subscribe()
appels àObservable
s au sein de leur classe code.Nous appelons alors
this.ngUnsubscribe.next(); this.ngUnsubscribe.complete();
dans notrengOnDestroy()
méthodes.Le secret de la sauce (comme cela a déjà été noté par @metamaker) est d'appeler
takeUntil(this.ngUnsubscribe)
avant chacune de nos.subscribe()
appels, qui permettra de garantir à tous les abonnements seront nettoyés, lorsque le composant est détruit.Exemple:
Remarque: Il est important d'ajouter le
takeUntil
opérateur en dernier pour éviter les fuites avec des intermédiaires observables dans l'opérateur de la chaîne.--- Edit 2 (2016/12/28)
Source 5
L'angle de tutoriel, le chapitre Routage indique désormais le suivant: "Le Routeur gère les observables et localise les abonnements. Les abonnements sont nettoyés lorsque le composant est détruit, la protection contre les fuites de mémoire, de sorte que nous n'avons pas besoin de vous désinscrire de la route des paramètres Observables." - Marque Rajcok
Voici un discussion sur le Github de questions pour l'angle d'docs concernant Routeur Observables où Paroisse Bell mentionne que des éclaircissements pour tout ceci est dans les travaux.
--- Edit 1
Source 4
Dans ce vidéo de NgEurope Rob Wormald également dit que vous n'avez pas besoin de vous désinscrire de Routeur Observables. Il mentionne aussi la
http
service etActivatedRoute.params
dans ce la vidéo à partir de novembre 2016.--- Réponse Originale À Cette Question
TLDR:
Pour cette question, il y a (2) types de
Observables
- finis valeur et infini valeur.http
Observables
produire finis (1) les valeurs et quelque chose comme un DOMevent listener
Observables
produire infini valeurs.Si vous avez manuellement appel
subscribe
(n'utilisant pas async pipe), puisunsubscribe
de infiniObservables
.Ne vous inquiétez pas à propos de finis ceux,
RxJs
de prendre soin d'eux.Source 1
J'ai dégotté une réponse de Rob Wormald Angulaire du Gitter ici.
Il déclare (j'ai réorganisé pour la clarté et l'emphase est mienne)
Aussi qu'il mentionne dans ce vidéo youtube sur des Observables qui
they clean up after themselves
... dans le contexte d'Observables quicomplete
(comme des Promesses, toujours parfaits parce qu'ils sont toujours la production de valeur 1 et se terminant - nous n'avons jamais inquiet au sujet de vous désabonner de Promesses pour s'assurer qu'ils nettoyerxhr
des écouteurs d'événement, non?).Source 2
Également dans le Rangle guide Angulaire 2 il lit
Lorsque le membre de phrase
our Observable has a longer lifespan than our subscription
appliquer?Elle s'applique lorsqu'un abonnement est créé à l'intérieur d'un composant qui est détruit avant (ou pas long avant) le
Observable
complète.J'ai lu ce sens que si nous sommes abonnés à un
http
demande ou à une observable qui émet des 10 valeurs et notre composant est détruit avant quehttp
demande les rendements ou les 10 valeurs ont été émises, nous sommes toujours ok!Lors de la demande de retour ou de la 10e valeur est enfin émis le
Observable
sera terminé et que toutes les ressources seront nettoyés.Source 3
Si l'on regarde cet exemple de la même Rangle guide, nous pouvons voir que la
Subscription
àroute.params
nécessite uneunsubscribe()
parce que nous ne savons pas quand cesparams
va cesser de les changer (par émission de nouvelles valeurs).Le composant pourrait être détruit par de naviguer à l'extérieur, auquel cas le paramètre de route sera probablement encore être en train de changer (ils pourraient techniquement le modifier jusqu'à ce que l'application se termine) et les ressources allouées à la souscription serait encore alloués car il n'a pas été un
completion
.complete()
être appelé sur ces sujets dansngOnDestroy
? Qui aurait le nettoyage des abonnements et chaque abonnement aurait la possibilité de nettoyer, de ce que jamais il a utilisé, dans son complet de gestionnaire, droit?complete()
par lui-même semble ne pas nettoyer les abonnements. Cependant l'appel denext()
et puiscomplete()
fait, je croistakeUntil()
ne s'arrête que lorsqu'une valeur est produit, pas lorsque la séquence est terminée.Subject
l'intérieur d'un composant et de basculement avecngIf
pour déclencherngOnInit
etngOnDestroy
montre, que l'objet et de ses abonnements ne seront jamais complètes ou obtenir éliminés (accroché jusqu'à unfinally
-opérateur à l'abonnement). Je dois appelerSubject.complete()
dansngOnDestroy
, de sorte que les abonnements peuvent nettoyer après eux-mêmes.Subject
s peut-être dans l'ensemble d'observables qui Angulaire va nettoyer pour vous, si ce n'est pas le cas, alors la solution ci-dessus doivent être utilisés.takeUnitl
approche, nous n'avons jamais à vous désinscrire manuellement à partir des observables? Est-ce le cas? En outre, pourquoi avons-nous besoin d'appelernext()
dans lengOnDestroy
, pourquoi ne pas simplement appelercomplete()
?complete()
ne déclenche pastakeUntil()
. Mais il ne nettoyer langUnsubscribe
Sujet. Doncnext()
nettoie tous les autres etcomplete()
nettoie de lui-même.takeUntil
dit qu'il est à l'écoute de l'observable, soit émettre une valeur ou d'une notification complète, donc il semble que tout le qualifiant decomplete
sur le sujet est assez.Returns the values from the source observable sequence until the other observable sequence or Promise produces a value.
à la Recherche à la source lorsque l'takeUntil Observateur appellenext
la source complète. @luciole mentionne ci-dessus que l'appelcomplete()
seul ne semble pas faire l'affaire.valueChanges
d'unFormControl
qui est une partie d'un composant donné? Dois-je encore besoin de vous désabonner?valueChanges
Observable est combiné avec d'autres observables qui vivent plus longtemps que la durée de vie du composant, alors oui, vous devez utiliser le schéma ci-dessus. Mais si vous ne vous abonnant à lavalueChanges
Observable, alors il sera détruit/nettoyé lorsque le composant (et la forme) sont détruits..complete()
est appelé sur eux. Ceci est un exemple d'où le fait d'avoir unngUnsubscribe: Subject<void>
permettrait de mieux gérer tous les autres abonnements (que ce soit à partir des Observables fournis par les événements DOM, injectable de services ou d'autres locauxSubject
s)..unsubscribe()
sur chaque abonnement (viafor ... of
), mais en utilisant.takeUntil(sub)
ou.pipe(takeUntil(sub))
est le plus rxjs-ish approcheasync pipe
). RxJs permet de vous faire aller un long chemin vers ne pas avoir à appelerunsubscribe()
lorsqu'il est utilisé avecasync pipe
par la combinaison et la manipulation des Observables au sein de votre composante. Vous pouvez également souventasync pipe
d'une valeur dans une muette du composant@Input()
et de travailler avec la valeur brute à partir de ce point en avant. Je trouve lengUnsubscribe()
solution utile lorsque Observables obtenir de très complexe, mais je ne sais pas si elle doit être la solution par défaut.this.ngUnsubscribe.complete();
. Aucune personne de l'extérieur fait référence à ce sujet . Et tous les abonnements qui ont touché ce sujet,ont été achevés. Alors pourquoi ?AsyncPipe
) dans le composant. Nous nous connectons tous les abonnements à cette ressource (ngUnsubscribe
) et quand il est nettoyé le reste sera trop. Mais nous avons encore à nettoyerngUnsubscribe
. Si nous n'avons pascomplete()
ngUnsubscribe
puis il va continuer à vivre sur une fois que le composant est supprimé.ngUnsubscribe.complete()
. Je pense toujours que c'est une bonne habitude.private alive = true
....takeWhile(() => this.alive)
Et dans lengOnDestroy()
défini à false:this.alive = false
. Je ne vois pas pourquoi nous avons besoin d'utiliser un autre Sujet...takeUntil
opérateur devrait être le dernier à éviter les fuites avec des intermédiaires observables dans l'opérateur de la chaîne.lettable
opérateurs aujourd'hui appelépipeable
opérateurs, je crois que tout détaillé devrait toujours s'appliquer. Vous souhaitez utiliser lesimport { takeUntil } from 'rxjs/operators'
au lieu de la mutation de l'importationimport 'rxjs/add/operator/takeUntil';
Subject
(même si vous n'allez pas l'utiliser), de sorte que vous avez, par exemple,Subject<boolean>
. Qui est:private ngUnsubscribe: Subject<boolean> = new Subject();
Vous n'avez pas besoin d'avoir des tas d'abonnement et de désabonnement manuellement. Utilisation Sujet et takeUntil combo pour gérer les abonnements comme un boss:
Approche Alternative, qui a été proposé par @acumartini dans les commentaires, utilise takeWhile au lieu de takeUntil. Vous préférerez peut-être, mais l'esprit que de cette façon, votre Observables de l'exécution ne sera pas annulée sur ngDestroy de votre composant (par exemple, lorsque vous faites beaucoup de temps de calculs ou d'attendre que les données à partir du serveur). La méthode, qui est basée sur takeUntil, n'a pas cet inconvénient et conduit à l'annulation immédiate de la demande. Grâce à @AlexChe pour des explications détaillées dans les commentaires.
Voici donc le code:
takeUntil
de la documentation pour voir l'explication de comment ça fonctionne xgrommx.github.io/rx-livre/content/observables/.... En paramètre, il n'accepte que des Observables | Promesse.takeUntil
ettakeWhile
. L'ancien désabonner à partir de la source observables immédiatement quand on tire, tandis que le second se désinscrit seulement dès qu'une nouvelle valeur est produite par la source observables. Si la production de valeur par la source observable est une ressource consommer de l'opération, le choix entre les deux peut aller au-delà des préférences de styles. Voir le plunktakeUntil
vstakeWhile
, cependant, pas pour notre cas précis. Lorsque nous avons besoin de vous désabonner auditeurs composant destruction, nous sommes juste vérifier les valeur booléenne comme() => alive
danstakeWhile
, donc, à tout moment/la consommation de mémoire d'opérations ne sont pas utilisés et la différence est assez beaucoup sur le style (ofc, pour ce cas précis).Observable
, qui en interne mines certains crypto-monnaie et déclenche unnext
événement pour tous les extraits de pièce de monnaie, et de l'exploitation d'une telle pièce prend une journée. AvectakeUntil
nous permettra de vous désabonner à partir de la source de l'exploitation minièreObservable
immédiatement une foisngOnDestroy
est appelée lors de la destruction. Ainsi, l'exploration deObservable
fonction est en mesure d'annuler l'opération immédiatement au cours de ce processus.takeWhile
, dans lengOnDestory
nous venons de définir la variable booléenne. Mais l'exploration deObservable
fonction peut-être encore du travail pour un jour, et alors seulement, pendant qu'il estnext
appel il va réaliser qu'il ya pas d'abonnement actif et doit annuler.Probably, this.alive = false MAY not be required here
est de la désinformation. Vous avez une forte référence jamais changement detrue
àfalse
ouundefined
, sauf si vous explicitement définie non définie.La classe d'Abonnement a une caractéristique intéressante:
Vous pouvez créer une Souscription global de l'objet, qui regroupe tous vos abonnements.
Vous faites cela en créant un vide d'Abonnement et de ajoutant des abonnements à l'aide de son
add()
méthode. Lorsque votre composant est détruit, il vous suffit de vous désabonner de la souscription total.takeUntil
approche par rapport à cette approche de la perception des contributions et de l'appel deunsubscribe
. (Cette approche semble beaucoup plus clair pour moi.)this.subscriptions
est nullsub = subsciption.add(..).add(..)
parce que dans de nombreux cas, il produit des résultats inattendus github.com/ReactiveX/rxjs/issues/2769#issuecomment-345636477Certaines des meilleures pratiques concernant les phénomènes observables désinscriptions à l'intérieur des composants Angulaires:
Une citation de
Routage & Navigation
Et de suivre les liens suivants:
http
observablesJ'ai recueilli les meilleures pratiques concernant les phénomènes observables désinscriptions à l'intérieur des composants Angulaires de partager avec vous:
http
observables de désabonnement est conditionnelle, et nous devrions prendre en compte les effets de l' 's'abonner callback' en cours d'exécution une fois que le composant est détruit sur une base de cas par cas. Nous savons que angulaires se désinscrit et nettoie lahttp
observables lui-même (1), (2). Si cela est vrai du point de vue des ressources, il dit seulement la moitié de l'histoire. Disons que nous parlons en appelant directementhttp
à partir de l'intérieur d'une composante, et lehttp
réponse a pris plus de temps que nécessaire si l'utilisateur a fermé la composant. Lesubscribe()
gestionnaire sera toujours appelé, même si le volet est fermé et détruit. Cela peut avoir des effets secondaires indésirables, et dans le pire des scénarios de quitter l'état de l'application cassé. Il peut aussi causer des exceptions si le code dans la fonction de rappel essaie de l'appeler quelque chose qui vient d'être éliminés. Cependant, et en même temps parfois, ils sont souhaitées. Comme, disons que vous êtes en train de créer un client e-mail et vous déclencher un son lorsque l'e-mail envoi - bien que vous ayez encore envie que ça se produire même si le volet est fermé (Huit).AsyncPipe
autant que possible, car il automatiquement désabonner à partir de l'observable sur les composantes de la destruction.ActivatedRoute
observables commeroute.params
si elles sont souscrites à l'intérieur d'un nid (Ajouté à l'intérieur de tpl avec le composant sélecteur) ou composant dynamique, car ils peuvent être souscrites nombre de fois aussi long que le parent/composant hôte existe. Pas besoin de vous désabonner dans d'autres scénarios, comme mentionné dans la citation ci-dessus deRoutage & Navigation
docs.Remarque: Concernant l'étendue des services, j'.e les fournisseurs de composants, ils sont détruits lorsque le composant est détruit. Dans ce cas, si nous souscrivons à observable à l'intérieur de ce fournisseur, nous devrions envisager de vous désabonner en utilisant le
OnDestroy
cycle de vie de crochet qui sera appelée lorsque le service est détruit, selon les docs.takeUntil
(3) ou vous pouvez utiliser cettenpm
package mentionné à (4) La meilleure façon de vous désabonner à partir de phénomènes Observables dans Angulaire.FormGroup
observables commeform.valueChanges
etform.statusChanges
Renderer2
service commerenderer2.listen
HostListener
comme angulaire de soucis bien sur la façon de retirer les écouteurs d'événement si nécessaire et empêche tout risque de fuite de mémoire due à des liaisons d'événements.Une belle pointe finale: Si vous ne savez pas si une observable est automatiquement désabonné/terminé ou pas, ajouter un
complete
de rappel àsubscribe(...)
et vérifier si elle est appelée lorsque le composant est détruit.ngOnDestroy
est appelée lorsque le service est fourni à un niveau autre que le niveau de la racine par exemple explicitement dans un composant qui plus tard est supprimé. Dans ces cas, vous devez vous désabonner de services interne observablesngOnDestroy
, ce qui est toujours appelé lorsque les services sont détruits github.com/angular/angular/commit/...Feel free to unsubscribe anyway. It is harmless and never a bad practice.
et concernant votre question, ça dépend. Si le composant enfant est initié à plusieurs reprises (Par exemple, ajouté à l'intérieur dengIf
ou chargé dynamiquement), vous devez annuler votre inscription, pour éviter l'ajout de plusieurs abonnements à la même observateur. Sinon pas besoin. Mais je préfère vous désabonner à l'intérieur du composant enfant ce qui la rend plus réutilisable et isolé de la façon dont il pourrait être utilisé.form.valueChanges
(ou statusChanges) pourrait survivre et de faire du mal lorsque le composant est détruit. OMI votre règle s'applique uniquement pour les abonnements à des formes non créé dans le propre composant ou lorsque les abonnements sont créés plusieurs fois pendant le direct.Il dépend. Si en appelant
someObservable.subscribe()
, vous commencez à la tenue de certaines ressources qui doivent être manuellement libérée lorsque le cycle de vie du composant est terminée, alors vous devriez appelertheSubscription.unsubscribe()
pour empêcher la fuite de mémoire.Nous allons regarder de plus près à votre exemples:
getHero()
retourne le résultat dehttp.get()
. Si vous regardez dans l'angle de 2 le code source,http.get()
crée deux écouteurs d'événement:et en appelant
unsubscribe()
, vous pouvez annuler la demande ainsi que les auditeurs:Noter que
_xhr
de la plate-forme, mais je pense qu'il est sûr de supposer que c'est unXMLHttpRequest()
dans votre cas.Normalement, c'est assez de preuves pour justifier un manuel
unsubscribe()
appel. Mais selon ce WHATWG spec, leXMLHttpRequest()
est soumise à la collecte des déchets une fois qu'il est "fait", même si il y a des écouteurs d'événement attaché à elle. Donc je suppose que c'est pourquoi angulaire 2 guide officiel qui ometunsubscribe()
et vous permet de GC nettoyer les auditeurs.Comme pour votre deuxième exemple, il dépend de la mise en œuvre de
params
. À compter d'aujourd'hui, l'angle de guide officiel n'affiche plus de se désabonner deparams
. J'ai regardé dans src encore et a constaté queparams
est un juste un BehaviorSubject. Depuis aucun cas, les auditeurs ou des minuteries ont été utilisés, et pas de variables globales ont été créé, il devrait être sûr d'omettreunsubscribe()
.La ligne de fond à votre question qui est toujours d'appel
unsubscribe()
une protection contre la fuite de mémoire, sauf si vous êtes certain que l'exécution de l'observable n'est pas de créer des variables globales, ajouter des écouteurs d'événement, régler les minuteries, ou faire autre chose qui entraîne des fuites de mémoire.En cas de doute, regardez dans la mise en œuvre de cette observable. Si l'observable a écrit nettoyer une partie de la logique dans ses
unsubscribe()
, qui est généralement de la fonction qui est renvoyé par le constructeur, alors vous avez une bonne raison de réfléchir sérieusement à l'appel deunsubscribe()
.Angulaire 2 la documentation officielle fournit une explication sur le moment de vous désinscrire et quand il peut être ignoré en toute sécurité. Jetez un oeil à ce lien:
https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectionnel-service
Recherchez le paragraphe avec la rubrique Parents et les enfants à communiquer par l'intermédiaire d'un service de et puis la boîte bleue:
J'espère que cela vous aide.
Basée sur : À l'aide de l'héritage de Classe à crochet Angulaire 2 composante du cycle de vie
Une autre approche générique:
JS:
Et d'utilisation :
JS:
this.componentDestroyed$.next()
appel comme la solution retenue par sean ci-dessus...Depuis seangwright la solution de (Edition 3) semble être très utile, j'ai aussi trouvé que c'était une douleur pour le pack de cette fonctionnalité dans le composant de base, et le soupçon d'un autre projet, les coéquipiers de se souvenir de l'appel à super() sur ngOnDestroy pour activer cette fonction.
Cette réponse de fournir un moyen de libérer de super appel, et de faire "componentDestroyed$" une base de composant de base.
Et puis vous pouvez utiliser cette fonctionnalité librement par exemple:
Officielle de l'Édition #3 réponse (et variations) fonctionne bien, mais la chose qui me surprend est la "boue" de la logique d'entreprise autour de l'observable abonnement.
Voici une autre approche à l'aide de papiers d'emballage.
Fichier subscribeAndGuard.ts est utilisé pour créer un nouveau Observable extension pour envelopper
.subscribe()
et à l'intérieur de retour à la lignengOnDestroy()
.L'utilisation est la même que
.subscribe()
, sauf pour un supplément de premier paramètre le référencement du composant.Ici est un composant avec deux abonnements, l'un avec l'enveloppe et l'autre sans. Le seul inconvénient est qu'il doit mettre en œuvre OnDestroy (avec vide de corps, si vous le désirez), sinon Angulaire ne sais pas à appeler le enveloppés version.
Une démo plunker est ici
Une note supplémentaire:
Re Edit 3 - Le "Officielle" de la Solution, cela peut être simplifiée par l'utilisation de takeWhile() au lieu de takeUntil() avant d'abonnements, et un simple booléen plutôt qu'un autre Observable dans ngOnDestroy.
À la suite de la réponse par @seangwright, j'ai écrit une classe abstraite qui gère "infini" observables' abonnements dans les composants:
À utiliser, il suffit de l'étendre dans votre angulaire composant et d'appel de la
subscribe()
méthode comme suit:Il accepte aussi l'erreur et de compléter les rappels comme d'habitude, un observateur de l'objet, ou non, des rappels à tous. N'oubliez pas d'appeler
super.ngOnDestroy()
si vous êtes aussi à la mise en œuvre de cette méthode dans le composant enfant.Trouver ici une référence supplémentaire par Ben Lesh: RxJS: Ne pas se Désabonner.
J'ai essayé seangwright la solution de (Edition 3)
Qui ne fonctionne pas pour les Observables qui a créé par minuterie ou un intervalle.
Cependant, j'ai eu de travail en utilisant une autre approche:
J'aime les deux dernières réponses, mais j'ai vécu un problème si le sous-classe référencée
"this"
dansngOnDestroy
.Je l'ai modifié pour être présent, et il semble que cela a résolu le problème.
this.ngOnDestroy = () => { f.bind(this)(); this.componentDestroyed$.complete(); };
Vous avez généralement besoin de se désabonner quand les composants sont détruits, mais Angulaire va gérer de plus en plus que nous allons, par exemple dans la nouvelle version mineure de Angular4, ils ont cette section pour le routage de désabonnement:
L'exemple ci-dessous est un bon exemple de Angulaire de la création d'un composant et de le détruire après, regardez comment les composant implémente OnDestroy, si vous avez besoin d'onInit, vous pouvez également l'implémente dans votre composant, comme le met en œuvre
OnInit, OnDestroy
Un autre court-outre les cas mentionnés ci-dessus est:
En cas de désabonnement est nécessaire, l'opérateur suivants pour observable pipe méthode peut être utilisée
il peut être utilisé comme ceci:
L'opérateur enveloppements ngOnDestroy méthode de composant.
Important: l'opérateur doit être le dernier observables de la pipe.
dans un SPA à ngOnDestroy fonction (angulaire du cycle de vie) Pour chaque abonnez-vous vous devez de désabonnement il. avantage => pour prévenir l'état de devenir trop lourd.
par exemple:
dans component1 :
en service:
dans component2:
Pour la manipulation abonnement j'ai utiliser un "Unsubscriber" de la classe.
Ici est la Unsubscriber Classe.
Et Vous pouvez utiliser cette classe dans un composant /Service /Effet etc.
Exemple:
Vous pouvez utiliser les dernières
Abonnement
classe pour vous désabonner de la Observables avec des pas tellement bordélique code.Nous pouvons faire cela avec
normal variable
mais il seraoverride the last subscription
sur chaque nouveau abonnez-vous afin de l'éviter, et cette approche est très utile si vous travaillez avec plus de nombre de Obseravables, et le type de Obeservables commeBehavoiurSubject
etSujet
Abonnement
vous pouvez l'utiliser de deux façons,
vous pouvez pousser l'abonnement à la Matrice de
à l'aide de
add()
deSubscription
Un
Subscription
peut contenir enfant abonnements et vous désabonner de tous les. Cette méthode gère les erreurs possibles (par exemple, si un enfant abonnements sont nuls).Espère que cela aide.. 🙂