Comment annuler un abonnement dans Angular2? RxJS semble avoir une méthode de disposition, mais je n'arrive pas à comprendre comment y accéder. J'ai donc un code qui a accès à un EventEmitter et qui s'y abonne, comme ceci:
var mySubscription = someEventEmitter.subscribe(
(val) => {
console.log('Received:', val);
},
(err) => {
console.log('Received error:', err);
},
() => {
console.log('Completed');
}
);
Comment utiliser mySubscription
pour annuler l'abonnement?
Souhaitez-vous vous désabonner?
mySubscription.unsubscribe();
Je pensais avoir mis mes deux cents aussi. J'utilise ce motif:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'my-component',
templateUrl: 'my.component.html'
})
export class MyComponent implements OnInit, OnDestroy {
private subscriptions: Array<Subscription> = [];
public ngOnInit(): void {
this.subscriptions.Push(this.someService.change.subscribe(() => {
[...]
}));
this.subscriptions.Push(this.someOtherService.select.subscribe(() => {
[...]
}));
}
public ngOnDestroy(): void {
this.subscriptions.forEach((subscription: Subscription) => {
subscription.unsubscribe();
});
}
}
EDIT
J'ai lu la documentation l'autre jour et j'ai trouvé un modèle plus recommandé:
Avantages:
Il gère les nouveaux abonnements en interne et ajoute des vérifications soignées. Préférerait cette méthode dans la fonctionnalité :).
Les inconvénients:
Le flux de code et les abonnements ne sont pas clairement définis à 100%. La manière dont il traite les abonnements fermés et si tous les abonnements sont fermés si la désinscription est appelée n'est pas claire non plus (juste en regardant le code).
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
@Component({
selector: 'my-component',
templateUrl: 'my.component.html'
})
export class MyComponent implements OnInit, OnDestroy {
private subscription: Subscription = new Subscription();
public ngOnInit(): void {
this.subscription.add(this.someService.change.subscribe(() => {
[...]
}));
this.subscription.add(this.someOtherService.select.subscribe(() => {
[...]
}));
}
public ngOnDestroy(): void {
/*
* magic kicks in here: All subscriptions which were added
* with "subscription.add" are canceled too!
*/
this.subscription.unsubscribe();
}
}
J'aurais pensé que vous cherchiez la méthode de disposition sur Disposable .
la méthode subscribe renvoie un jetable ( lien )
Je n'arrive pas à le trouver plus explicitement dans la documentation, mais cela fonctionne ( jsbin ):
var observable = Rx.Observable.interval(100);
var subscription = observable.subscribe(function(value) {
console.log(value);
});
setTimeout(function() {
subscription.dispose();
}, 1000)
Bizarrement, la désinscription semble fonctionner pour vous alors que ça ne fonctionne pas pour moi ...
Beaucoup trop d’explications différentes de la désinscription sur Observables for ng2 m’ont pris beaucoup de temps pour trouver la bonne réponse. Vous trouverez ci-dessous un exemple de travail (j’essayais d’étrangler la souris).
import {Injectable, OnDestroy} from "@angular/core";
import {Subscription} from "rxjs";
@Injectable()
export class MyClass implements OnDestroy {
mouseSubscription: Subscription; //Set a variable for your subscription
myFunct() {
// I'm trying to throttle mousemove
const eachSecond$ = Observable.timer(0, 1000);
const mouseMove$ = Observable.fromEvent<MouseEvent>(document, 'mousemove');
const mouseMoveEachSecond$ = mouseMove$.sample(eachSecond$);
this.mouseSubscription = mouseMoveEachSecond$.subscribe(() => this.doSomethingElse());
}
doSomethingElse() {
console.log("mouse moved");
}
stopNow() {
this.mouseSubscription.unsubscribe();
}
ngOnDestroy() {
this.mouseSubscription.unsubscribe();
}
}
ngOnDestroy(){
mySubscription.unsubscribe();
}
Préférer la désinscription de la désinscription de rxjs lors de la destruction du composant, c'est-à-dire la suppression de DOM pour éviter les fuites de mémoire inutiles
Je préfère utiliser personnellement un sujet pour fermer tous les abonnements qu'un composant peut avoir à l'étape du cycle de vie de la destruction, ce qui peut être réalisé de la manière suivante:
import { Component} from '@angular/core';
import { Subject } from "rxjs/Rx";
@Component({
selector: 'some-class-app',
templateUrl: './someClass.component.html',
providers: []
})
export class SomeClass {
private ngUnsubscribe: Subject<void> = new Subject<void>(); //This subject will tell every subscriptions to stop when the component is destroyed.
//**********
constructor() {}
ngOnInit() {
this.http.post( "SomeUrl.com", {}, null ).map( response => {
console.log( "Yay." );
}).takeUntil( this.ngUnsubscribe ).subscribe(); //This is where you tell the subscription to stop whenever the component will be destroyed.
}
ngOnDestroy() {
//This is where we close any active subscription.
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
}
L'approche recommandée consiste à utiliser des opérateurs RxJS tels que l'opérateur takeUntil . Ci-dessous l'extrait de code montrant comment l'utiliser: -
import { Component, OnInit, OnDestroy } from '@angular/core';
import { interval, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent implements OnInit, OnDestroy {
private ngUnsubscribe = new Subject();
constructor() { }
ngOnInit() {
var observable1 = interval(1000);
var observable2 = interval(2000);
observable1.pipe(takeUntil(this.ngUnsubscribe)).subscribe(x => console.log('observable1: ' + x));
observable2.pipe(takeUntil(this.ngUnsubscribe)).subscribe(x => console.log('observable2: ' + x));
}
ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
}
Vous pouvez trouver une explication détaillée du sujet ici
Utilisation
if(mySubscription){
mySubscription.unsubscribe();
}