कोणीय 4+ ngOnDestroy () सेवा में - अवलोकन योग्य नष्ट करें


103

एक कोणीय अनुप्रयोग में हमारे पास ngOnDestroy()एक घटक / निर्देश के लिए जीवन चक्र हुक होता है और हम इस हुक का उपयोग वेधशालाओं को बंद करने के लिए करते हैं।

मैं एक ऐसी @injectable()सेवा में बनाए गए क्लीयर / डेस्ट्ररी ऑब्जर्व करना चाहता हूं । मैंने कुछ पोस्टों को यह कहते हुए देखा कि ngOnDestroy()इसका उपयोग किसी सेवा में भी किया जा सकता है।

लेकिन, क्या यह एक अच्छा अभ्यास है और ऐसा करने का एकमात्र तरीका है और इसे कब बुलाया जाएगा? कृपया स्पष्ट करें।

जवाबों:


119

OnDestroy जीवनचक्र हुक प्रदाताओं में उपलब्ध है। डॉक्स के अनुसार:

जीवनचक्र हुक जिसे निर्देश, पाइप या सेवा नष्ट होने पर कहा जाता है।

यहाँ एक उदाहरण है :

@Injectable()
class Service implements OnDestroy {
  ngOnDestroy() {
    console.log('Service destroy')
  }
}

@Component({
  selector: 'foo',
  template: `foo`,
  providers: [Service]
})
export class Foo implements OnDestroy {
  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)
  }
}

ध्यान दें कि ऊपर दिए गए कोड Serviceमें एक उदाहरण है जो Fooघटक का है, इसलिए इसे नष्ट होने Fooपर नष्ट किया जा सकता है।

प्रदाताओं के लिए जो रूट इंजेक्टर से संबंधित हैं, यह एप्लिकेशन नष्ट होने पर होगा, यह कई बूटस्ट्रैप के साथ मेमोरी लीक से बचने के लिए सहायक है, अर्थात परीक्षणों में।

जब माता-पिता इंजेक्टर से एक प्रदाता को बच्चे के घटक में सदस्यता दी जाती है, तो यह घटक को नष्ट करने पर नष्ट नहीं होगा, घटक में सदस्यता समाप्त करने के लिए यह घटक की जिम्मेदारी है ngOnDestroy(जैसा कि कोई अन्य उत्तर बताता है)।


नहीं class Service implements OnDestroy ? और आपको क्या लगता है जब यह कहा जाता है यदि सेवा मॉड्यूल स्तर पर प्रदान की जाती है
शूमेल

1
implements OnDestroyकुछ भी प्रभावित नहीं करता है लेकिन पूर्णता के लिए जोड़ा जा सकता है। यह तब कहा जाएगा जब एक मॉड्यूल नष्ट हो जाता है, जैसेappModule.destroy() । यह कई ऐप इनिशियलाइज़ेशन के लिए उपयोगी हो सकता है।
एस्टुस फ्लास्क

1
सेवाओं का उपयोग करने वाले प्रत्येक घटक के लिए सदस्यता समाप्त करना आवश्यक है?
अली अब्बासजादे

2
प्लंकेर मेरे लिए काम नहीं कर रहा था, इसलिए यहाँ एक StackBlitz उदाहरण का संस्करण है: stackblitz.com/edit/angular-mggk9b
compuguru

1
मुझे यह समझने में थोड़ी परेशानी हुई। लेकिन इस चर्चा ने मुझे स्थानीय और वैश्विक सेवाओं के बीच के अंतर को समझने में मदद की: stackoverflow.com/questions/50056446/… "चाहे आपको" सफाई करनी हो "या आपकी सेवा के दायरे से निर्भर न हो, मुझे लगता है।
जैस्मिन

25

अपनी सेवा में एक चर बनाएं

subscriptions: Subscriptions[]=[];

अपनी प्रत्येक सदस्यता को सरणी के रूप में पुश करें

this.subscriptions.push(...)

एक dispose()विधि लिखिए

dispose(){
this.subscriptions.forEach(subscription =>subscription.unsubscribe())

इस विधि को अपने घटक से ngOnDestroy के दौरान कॉल करें

ngOnDestroy(){
   this.service.dispose();
 }

आपके जवाब के लिए धन्यवाद। क्या हमारे पास कोई विचार है जब यह ngOnDestroy कहा जाएगा। ?
mperle

हां यह कहता है कि निर्देश या घटक के नष्ट होने से पहले इसकी सफाई होती है। लेकिन मैं सिर्फ यह समझना चाहता हूं कि क्या यह सेवा के लिए भी लागू है?
mperle

मॉड्यूल अनलोड किए जाने पर कोई सेवा साफ़ नहीं की जाएगी
अरविंद

2
जीवन चक्र हुक नहीं लागू करने के लिए कर रहे हैं@injectables
अरविंद

@ अरविंद मुझे यकीन नहीं है कि जब उन्हें पेश किया गया था, लेकिन वे हैं
एस्टुस फ्लास्क

11

मैं takeUntil(onDestroy$)पाइपलाइन ऑपरेटरों द्वारा सक्षम इस पैटर्न को पसंद करता हूं । मुझे यह पसंद है कि यह पैटर्न अधिक संक्षिप्त, अधिक स्वच्छ है, और यह स्पष्ट रूप से के निष्पादन पर एक सदस्यता को मारने के इरादे को व्यक्त करता हैOnDestroy जीवन चक्र हुक के ।

यह पैटर्न सेवाओं के साथ-साथ उन घटकों के लिए भी काम करता है जो इंजेक्ट किए गए वेधशालाओं की सदस्यता लेते हैं। नीचे दिए गए कंकाल कोड को आपको अपनी सेवा में पैटर्न को एकीकृत करने के लिए पर्याप्त विवरण देना चाहिए। कल्पना कीजिए कि आप एक सेवा का आयात कर रहे हैं, जिसे 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();
  }

जब / कैसे सदस्यता समाप्त करने का विषय यहां बड़े पैमाने पर कवर किया गया है: कोणीय / RxJs मुझे कब सदस्यता छोड़ना चाहिए?


5

बस स्पष्ट करने के लिए - आपको नष्ट करने की आवश्यकता नहीं है, Observablesलेकिन केवल उनके लिए बनाई गई सदस्यता।

ऐसा लगता है जैसे दूसरों ने इंगित किया है कि आप अब ngOnDestroyसेवाओं के साथ भी उपयोग कर सकते हैं । लिंक: https://angular.io/api/core/OnDestroy


1
क्या आप इसके बारे में अधिक विस्तार से बता सकते हैं
अरविंद

2

टोकन का उपयोग करते समय सावधानी

जितना संभव हो सके अपने आवेदन को मॉड्यूलर बनाने की कोशिश में, मैं अक्सर एक घटक को सेवा प्रदान करने के लिए प्रदाता टोकन का उपयोग करूंगा। ऐसा लगता है कि ये उनके ngOnDestroyतरीके नहीं कहलाते हैं :-(

जैसे।

export const PAYMENTPANEL_SERVICE = new InjectionToken<PaymentPanelService>('PAYMENTPANEL_SERVICE');

एक घटक में एक प्रदाता अनुभाग के साथ:

 {
     provide: PAYMENTPANEL_SERVICE,
     useExisting: ShopPaymentPanelService
 }

घटक के निस्तारण के समय मेरे ShopPaymentPanelServiceपास इसकी ngOnDestroyविधि नहीं है । मुझे यह मुश्किल तरीका लगा!

वर्कअराउंड सेवा के साथ संयोजन प्रदान करना है useExisting

[
   ShopPaymentPanelService,

   {
       provide: PAYMENTPANEL_SERVICE,
       useExisting: ShopPaymentPanelService
   }
]

जब मैंने ऐसा किया तो ngOnDisposeउम्मीद के मुताबिक बुलाया गया था।

यकीन नहीं होता कि यह बग है या नहीं लेकिन बहुत अप्रत्याशित है।


महान संकेत! मैं सोच रहा था कि यह मेरे मामले में काम क्यों नहीं कर रहा था (मैं ठोस क्रियान्वयन के लिए टोकन के रूप में अमूर्त वर्ग-इंटरफ़ेस का उपयोग कर रहा था)।
आंद्रेई सिनिट्सन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.