Angular2 में सदस्यता कैसे रद्द करें


81

Angular2 में सदस्यता कैसे रद्द करता है? RxJS के पास एक डिस्पोज़ करने की विधि है, लेकिन मैं यह नहीं जान सकता कि इसे कैसे एक्सेस किया जाए। तो मेरे पास कोड है जो एक EventEmitter तक पहुंचता है और इसे इस तरह से सब्सक्राइब करता है:

var mySubscription = someEventEmitter.subscribe(
    (val) => {
        console.log('Received:', val);
    },
    (err) => {
        console.log('Received error:', err);
    },
    () => {
        console.log('Completed');
    }
);

मैं mySubscriptionसदस्यता को रद्द करने के लिए कैसे उपयोग कर सकता हूं ?


2
FYI करें - यदि आप रिएक्टिव चीजें करने जा रहे हैं, तो Angular's EventEmitter के बजाय एक Subject का उपयोग करें - इसकी कोई गारंटी नहीं है कि यह Subject का सुपरक्लास बना रहेगा। EventOmitter का उपयोग केवल @Output इवेंट्स के लिए करें।
रॉबटर्मडाल

जवाबों:


121

क्या आप सदस्यता समाप्त करना चाहते हैं?

mySubscription.unsubscribe();

4
अच्छे भगवान। मैंने कसम खाई थी कि मैंने पहले ही कोशिश की थी। मैंने आरएक्सजेएस स्रोत को देखा और ऐसा लग रहा था कि यह क्या है। मुझे कोई भिन्न त्रुटि हुई होगी जिससे मुझे समस्याएँ हुईं। धन्यवाद।
माइकल ओरिएल

1
यह अच्छी तरह से काम करता है लेकिन मैं mySubscriptionटाइपस्क्रिप्ट में किस प्रकार का उत्सुक हूं। मैं mySubscription: anyअपनी कक्षा में लिखने से बचना चाहता हूँ ।
पैराडाइट

11
@ अपरादी import { Subscription } from "rxjs";और सदस्यता के लिए if (!mySubscription.closed) { mySubscription.unsubscribe(); }
लिली

9
import { Subscription } from 'rxjs/Subscription';आपके पैकेज के आकार को नीचे रखने में मदद करेगा
paul

50

मैंने सोचा कि मैं अपने दो सेंट में भी डाल दिया। मैं इस पैटर्न का उपयोग करता हूं:

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();
        });
    }
}

संपादित करें

मैंने दूसरे दिन प्रलेखन पढ़ा और एक अधिक अनुशंसित पैटर्न पाया:

ReactiveX / RxJS / सदस्यता

पेशेवरों:

यह आंतरिक रूप से नए सदस्यता का प्रबंधन करता है और कुछ साफ चेक जोड़ता है। सुविधा में इस विधि को पसंद करेंगे :)।

विपक्ष:

यह 100% स्पष्ट नहीं है कि कोड प्रवाह क्या है और सदस्यता कैसे प्रभावित होती है। न ही यह स्पष्ट है (केवल कोड को देखने से) यह बंद सदस्यता के साथ कैसे व्यवहार करता है और यदि सदस्यता समाप्त हो जाती है तो सभी सदस्यताएं बंद हो रही हैं।

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();
    }
}

2
मैं भी इस का उपयोग करें, यह एक घटक में अधिक सदस्यता के अच्छी तरह से तराजू है।
weltschmerz

1
कोई "जादू" नहीं है - यह डिजाइन द्वारा है: "सदस्यता भी एक साथ रखी जा सकती है, ताकि एक सदस्यता के अनसब्सक्राइब () की कॉल एक से अधिक सदस्यता समाप्त कर सके। आप यह कर सकते हैं" एक सदस्यता को दूसरे में "जोड़कर:" gubub
मीटाइ.कॉम

एक और स्पष्ट दृष्टिकोण है जिसमें आप रुचि ले सकते हैं। takeWhileऑपरेटर का उपयोग करना । दृष्टिकोण यहाँ वर्णित है: brianflove.com/2016/12/11/anguar-2-unsubscribe-observables
vdshb

एक की जाँच करें वैकल्पिक समाधान है, जो takeUntil उपयोग कर रहा है। विभिन्न विकल्पों पर विचार करते हुए एक समृद्ध और दिलचस्प चर्चा है।
एलेक्स क्लॉस

8

EDIT: यह RxJS 5 पर लागू नहीं होता है, जो कि angular2 का उपयोग कर रहा है।

मैंने सोचा होगा कि आप डिस्पोजेबल पर डिस्पोजल विधि की तलाश कर रहे हैं ।

सदस्यता विधि एक डिस्पोजेबल ( लिंक ) लौटाती है

मुझे यह डॉक्स में अधिक स्पष्ट रूप से नहीं मिल रहा है, लेकिन यह काम करता है ( jsbin ):

var observable = Rx.Observable.interval(100);

var subscription = observable.subscribe(function(value) {
   console.log(value);
});

setTimeout(function() {
  subscription.dispose();           
}, 1000)

अजीब बात है, सदस्यता समाप्त करना आपके लिए काम कर रहा है, जबकि यह मेरे लिए काम नहीं कर रहा है ...


आप शायद विभिन्न संस्करणों का उपयोग करें। Angular2 Rxjs5 पर है न?
user3743222

हाँ, कोणीय 2 RxJS 5 का उपयोग करता है
माइकल ओरील

1
बस। यहां पाया जा सकता है
ईएस 7 ऑब्जर्वेबल

4

एनजी 2 के लिए वेब्सवेबल्स पर अनसब्सक्राइब के कई अलग-अलग स्पष्टीकरणों ने, मुझे सही उत्तर खोजने के लिए उम्र लिया। नीचे एक काम करने का उदाहरण है (मैं मूसमोव को कुचलना चाह रहा था)।

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();
  }
  
}


2
ngOnDestroy(){
   mySubscription.unsubscribe();
}

अनसब्सक्राइबिंग को रोकें rxjs को अनसब्सक्राइब करते हुए घटक को नष्ट कर रहे हैं अर्थात, आवश्यक मेमोरी लीक से बचने के लिए DOM से हटा दें


2

मैं व्यक्तिगत रूप से सब सब्जेक्ट को बंद करने के लिए एक घटक का उपयोग करना पसंद करता हूं जो कि जीवन चक्र के नष्ट होने वाले चरण में हो सकता है जो इस तरह से प्राप्त किया जा सकता है:

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();
  }
}

2

की सिफारिश की दृष्टिकोण जैसे RxJS ऑपरेटरों का उपयोग करने के लिए है takeUntil ऑपरेटर। नीचे कोड स्निपेट दिखाया गया है कि इसका उपयोग कैसे किया जाता है: -

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();
    }
}

आप विषय का विस्तृत विवरण यहां पा सकते हैं


हमें ngUnsubscribe.next () को कॉल करने की आवश्यकता क्यों है; in ngOnDestroy () विधि?
बिस्वा बंधु भंडारी

1

उपयोग

if(mySubscription){
  mySubscription.unsubscribe();
}

1
वास्तव में होना चाहिएif (!mySubscription.closed) { mySubscription.unsubscribe(); }
Llyle

-1
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { SomeAPIService } from '../some_file/someAPIService.service.ts

@Component({
  templateUrl: './your_Page.html',
  styleUrls: ['./your_Styles.scss']
})

export class (your class) implements OnInit, OnDestroy {
   // This is a subject variable at it simplest form 
     private unsubscribe$ = new Subject<void>();

     constructor (private someAPIService : SomeAPIService) {}
   
     ngOnit(): void { 
       this.someAPIService.getTODOlist({id:1})
        .pipe(takeUntil(this.unsubscribe$))
         .subscribe((value: SomeVariable) => {
         // What ever value you need is SomeVariable
      },)
    }


     ngOnDestroy(): void {
    // clears all, page subscriptions 
      this.unsubscribe$.next();
      this.unsubscribe$.complete();
     }
`}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.