2016-01-21 24 views
21

मेरे आवेदन में मेरे पास कुछ घटक हैं जो EventService के माध्यम से संवाद करते हैं।कोणीय 2, ngOnDestroy

@Injectable() 
export class EventService { 
    public myEvent: EventEmitter<any> = new EventEmitter(); 
    constructor() {} 
} 

यह सेवा एक EmitterComponent है कि घटना है जब एक बटन क्लिक किए जाने का उत्सर्जन करता है में इंजेक्ट किया जाता है

@Component({ 
    selector: 'emitter', 
    template: `<button (click)="onClick()">Click me</button>`, 
}) 
export class EmitterComponent { 
    constructor(private eventService:EventService) {} 
    onClick() { 
    this.eventService.myEvent.emit(); 
    } 
} 

और एक ReceiverComponent कि प्राप्त वेतन वृद्धि घटना के लिए और प्रत्येक घटना के लिए एक काउंटर सब्सक्राइब में

@Component({ 
    selector: 'receiver', 
    template: `Count: {{count}}`, 
}) 
export class ReceiverComponent { 
    public count = 0; 
    constructor(private eventService:EventService) { 
    this.eventService.myEvent.subscribe(() => this.count++;); 
    } 
} 

एप्लिकेशन में कई दृश्य हैं (इस उदाहरण में केवल दो): PageA और PageBEmitterComponent और ReceiverComponentPageA में हैं। हर बार जब मैं PageB पर जाता हूं और PageA पर वापस आ जाता हूं, तो एक नया ReceiverComponent बनाया जाता है और जब मैं EmitterComponent में बटन क्लिक करता हूं, तो ReceiverComponent का ईवेंट कॉलबैक फ़ंक्शन कई बार निष्पादित होता है।

इससे बचने के लिए मैं ngOnDestroy

ngOnDestroy() { 
    this.eventService.myEvent.unsubscribe(); 
} 

में myEvent से ReceiverComponent सदस्यता समाप्त, लेकिन यह निम्न अपवाद

EXCEPTION: Error during instantiation of ReceiverComponent!. 
ORIGINAL EXCEPTION: Error: Cannot subscribe to a disposed Subject 

मुझे लगता है कि कैसे बच सकते हैं क्या कारण हैं? सही तरीके से सदस्यता कैसे लें?

एक बेहतर समझ के लिए मैंने यह plunker बनाया है जहां आप कंसोल में त्रुटि और कुछ टिप्पणियां देख सकते हैं।

उत्तर

30

आपको .subscribe() से सदस्यता प्राप्त होती है। सदस्यता रद्द करने के लिए अपनी unsubscribe() विधि का उपयोग करें।

@Component({ 
    selector: 'receiver', 
    template: `Count: {{count}}`, 
}) 
export class ReceiverComponent { 
    public count = 0; 
    private subscription; 
    constructor(private eventService:EventService) { 
    this.subscription = this.eventService.myEvent.subscribe(() => this.count++;); 
    } 
    ngOnDestroy() { 
    this.subscription.unsubscribe(); 
    } 
} 

भी

+0

है कि मैं वास्तव में क्या किया था, लेकिन इस का कारण बनता है "त्रुटि: एक निपटाए विषय की सदस्यता नहीं कर सकते" जब मैं pageB को दृश्य बदलने और प्रतीत नहीं होता है वापस pageA – TizianoL

+3

करने के लिए जाना मुझे भी। क्या मैं कुछ भूल रहा हूँ? आपके प्रश्न में आप 'this.eventService.myEvent.unsubscribe();' vs 'subscription का उपयोग करते हैं। सदस्यता लें();'। –

+1

ओह, मुझे खेद है, मेरा बुरा, मैंने अंतर नहीं देखा। अब यह काम करता है, बहुत बहुत धन्यवाद! – TizianoL

2

मुझे लगता है कि देखें अपने जैसा कि नीचे वर्णित सदस्यता रोक नहीं करना चाहिए:

export class ReceiverComponent { 
    public count = 0; 
    private id; 

    constructor(private eventService:EventService) { 
    this.id = Date.now(); 
    console.log("ReceiverComponent constructor " + this.id); 
    this.subscription = this.eventService.myEvent.subscribe(() => { 
     console.log("count " + this.count + " (id ReceiverComponent instance: " + this.id + ")"); 
     this.count++; 
    }); 
    } 

    ngOnDestroy() { 
    console.log("onDestroy of ReceiverComponent " + this.id) 
    //this cause "Cannot subscribe to a disposed Subject." 
    //this.eventService.myEvent.unsubscribe(); 
    this.subscription.unsubscribe(); 
    } 
} 

वास्तव में, EventEmitter एस साझा किए गए अवलोकन हैं, यानी गर्म अवलोकन। यहां एक लिंक है जो आपको रूचि दे सकता है: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/creating.md

आशा है कि यह आप में मदद करता है, थियरी