EventEmitter का उचित उपयोग क्या है?


225

मैंने CustomHttp के अंदर Access EventEmitter Service जैसे प्रश्न पढ़े हैं जहाँ उपयोगकर्ता अपनी सेवा में EventEmitter का उपयोग करता है, लेकिन उसे इस टिप्पणी में इसका उपयोग न करने और सीधे अपनी सेवाओं में वेधशालाओं का उपयोग करने का सुझाव दिया गया था ।

मैंने इस प्रश्न को भी पढ़ा जहां समाधान बच्चे को EventEmitter पास करने और उसे सदस्यता देने का सुझाव देता है।

मेरा सवाल यह है: क्या मुझे, या मुझे EventEmitter को मैन्युअल रूप से सदस्यता नहीं लेनी चाहिए? मुझे इसका उपयोग कैसे करना चाहिए?



2
मार्क का अच्छा जवाब, हमेशा की तरह, लेकिन वास्तव में वह यह नहीं बताता कि मैंने क्यों समझाया। मैं इसे बंद करने के खिलाफ नहीं हूं, लेकिन मैं पहले उनकी राय चाहता हूं। @ मर्कराजकोक विचार?
एरिक मार्टिनेज

मैं इसे खुला रखना चाहूंगा (और मुझे यकीन है कि मैं यहां लोगों को इंगित करूंगा - मैंने यहां इंगित करने के लिए अपने अन्य उत्तर संपादित किए हैं!)। आपके उत्तर में कुछ अतिरिक्त जानकारी है। मैं हालांकि दो प्रश्न शीर्षक चाहता हूं ... दूसरा है "एक EventEmitter का उचित उपयोग क्या है?"
मार्क राजकोक

@MarkRajcok मैं उस शीर्षक को पसंद करता हूं, लेकिन यह वर्तमान उत्तर के साथ फिट नहीं होगा, इसलिए मैं इसे बाद में अपडेट करना सुनिश्चित करूंगा, इसका उपयोग कैसे करें और कैसे नहीं करना है, इसके उदाहरण जोड़ें। आपकी प्रतिक्रिया के लिए धन्यवाद :)
एरिक मार्टिनेज

@MarkRajcok ने सुझाव दिया (y), (कॉपी और पेस्ट किए गए शीर्षक को, सभी क्रेडिट्स को पेस्ट किया गया) के रूप में संपादित किया गया।
एरिक मार्टिनेज

जवाबों:


342

TL; DR :

नहीं, उन्हें मैन्युअल रूप से सदस्यता न दें, सेवाओं में उनका उपयोग न करें। उन्हें उपयोग करें जैसा कि प्रलेखन में केवल घटकों में घटनाओं का उत्सर्जन करने के लिए दिखाया गया है। कोणीय की अमूर्तता को पराजित न करें।

उत्तर:

नहीं, आपको इसे मैन्युअल रूप से सब्सक्राइब नहीं करना चाहिए।

EventEmitter एक कोणीय 2 अमूर्तता है और इसका एकमात्र उद्देश्य घटकों में घटनाओं का उत्सर्जन करना है। Rob Wormald की एक टिप्पणी का हवाला देते हुए

[...] EventEmitter वास्तव में एक कोणीय अमूर्तता है, और केवल घटकों में कस्टम ईवेंट का उत्सर्जन करने के लिए बहुत अधिक उपयोग किया जाना चाहिए। अन्यथा, बस Rx का उपयोग करें जैसे कि यह कोई अन्य पुस्तकालय था।

EventEmitter के प्रलेखन में यह वास्तव में स्पष्ट कहा गया है।

कस्टम ईवेंट का उत्सर्जन करने के लिए निर्देशों और घटकों द्वारा उपयोग करें।

इसका उपयोग करने में क्या गलत है?

Angular2 हमें कभी भी गारंटी नहीं देगा कि EventEmitter एक ऑब्जर्वेबल रहेगा। तो इसका मतलब है कि अगर यह बदल जाता है तो हमारे कोड को फिर से भरना। एकमात्र एपीआई जिसे हमें एक्सेस करना चाहिए वह है इसकी emit()विधि। हमें कभी भी EventEmitter की सदस्यता नहीं लेनी चाहिए।

इस वार्ड बेल की टिप्पणी में उपरोक्त सभी अधिक स्पष्ट है (लेख को पढ़ने के लिए अनुशंसित है, और उस टिप्पणी का उत्तर )। संदर्भ के लिए उद्धरण

EventEmitter पर ध्यान न देने योग्य होने के लिए गिनती मत करो!

भविष्य में उन अवलोकनीय परिचालकों पर भरोसा मत करो!

इन्हें जल्द ही हटा दिया जाएगा और संभवतः रिलीज से पहले हटा दिया जाएगा।

EventEmitter का उपयोग केवल बच्चे और माता-पिता के घटक के बीच होने वाले घटना बंधन के लिए करें। इसकी सदस्यता न लें। उन तरीकों में से कोई भी कॉल न करें। केवल कॉल करेंeve.emit()

उनकी टिप्पणी बहुत समय पहले रॉब की टिप्पणी के अनुरूप है।

तो, इसे ठीक से कैसे उपयोग करें?

बस अपने घटक से घटनाओं का उत्सर्जन करने के लिए इसका उपयोग करें। निम्नलिखित उदाहरण देखें।

@Component({
    selector : 'child',
    template : `
        <button (click)="sendNotification()">Notify my parent!</button>
    `
})
class Child {
    @Output() notifyParent: EventEmitter<any> = new EventEmitter();
    sendNotification() {
        this.notifyParent.emit('Some value to send to the parent');
    }
}

@Component({
    selector : 'parent',
    template : `
        <child (notifyParent)="getNotification($event)"></child>
    `
})
class Parent {
    getNotification(evt) {
        // Do something with the notification (evt) sent by the child!
    }
}

इसका उपयोग कैसे न करें?

class MyService {
    @Output() myServiceEvent : EventEmitter<any> = new EventEmitter();
}

वहीं रुक जाओ ... तुम पहले से ही गलत हो ...

उम्मीद है कि ये दो सरल उदाहरण EventEmitter के उचित उपयोग को स्पष्ट करेंगे।


1
आप का क्या मतलब है: directives : [Child]घटक परिभाषा में? यह संकलित नहीं लगता है, और मुझे यह Angular2 प्रलेखन में वर्णित नहीं मिला।
थीमाथैगियन 23

1
@ ईरिक: आपके उदाहरण में इसका उपयोग नहीं करने का तरीका बहुत स्पष्ट है, हमें एक सेवा में '@ ऑउटपुट' डेकोरेटर की आवश्यकता क्यों है?
trungk18

1
@themathmagician अनुसंधान के एक बिट के बाद, मैंने पाया यहाँ है कि directivesक्योंकि कीवर्ड बहिष्कृत कर दिया गया। declarationsकीवर्ड का उपयोग यहां या यहाँ@NgModule निर्देशित के रूप में करें
cjsimon

5
टोबी के हालिया जवाब पर कोई टिप्पणी? मुझे लगता है कि उसका जवाब आजकल स्वीकार किया जाना चाहिए।
अर्जन

7
@Eric जब आपने यह उत्तर लिखा तो आपने लिखा: 'ये जल्द ही पदावनत हो जाएंगे और संभवत: रिलीज से पहले हटा दिए जाएंगे', वार्ड बेल के हवाले से। लेकिन यह 2 साल पहले कहा गया था और अब हमारे पास कोणीय 6 है। क्या यह कथन अभी भी लागू होता है? मैं आधिकारिक डॉक में देखता हूं कि EventEmitter के पास अभी भी सदस्यता () विधि है, इसलिए मुझे लगता है कि अगर Google Rxjs विषयों पर EE को आधार बनाना बंद करना चाहता था तो वे पहले ही कर चुके थे। तो क्या आपको लगता है कि आपका मूल उत्तर अभी भी एंगुलर की वर्तमान स्थिति पर अच्छी तरह से फिट बैठता है?
नाद जी।

101

हां, आगे बढ़ो और इसका इस्तेमाल करो।

EventEmitterअंतिम कोणीय कोर एपीआई में एक सार्वजनिक, प्रलेखित प्रकार है। यह Observableअप्रासंगिक है या नहीं, इस पर आधारित है; अगर इसकी प्रलेखित emitऔर subscribeविधियां आपके लिए आवश्यक हैं, तो आगे बढ़ें और इसका उपयोग करें।

डॉक्स में भी कहा गया है:

Rx.Observable का उपयोग करता है, लेकिन इसे यहां बताए अनुसार काम करने के लिए एक एडाप्टर प्रदान करता है: https://github.com/jhusain/observable-spec

एक बार कल्पना का संदर्भ लागू होने के बाद, उस पर स्विच करें।

इसलिए वे एक Observableऐसी वस्तु चाहते थे जो एक निश्चित तरीके से व्यवहार करे, उन्होंने इसे लागू किया, और इसे सार्वजनिक किया। यदि यह केवल एक आंतरिक कोणीय अमूर्तता है जिसका उपयोग नहीं किया जाना चाहिए, तो उन्होंने इसे सार्वजनिक नहीं किया।

बहुत बार ऐसा होता है जब एक एमिटर के लिए उपयोगी होता है जो एक विशिष्ट प्रकार की घटनाओं को भेजता है। यदि आपका उपयोग मामला है, तो इसके लिए जाएं। यदि / जब वे जिस लिंक से जुड़ते हैं, उसका संदर्भ कार्यान्वयन उपलब्ध है, तो यह किसी अन्य पॉलिफिल की तरह ही ड्रॉप-इन प्रतिस्थापन होना चाहिए।

बस यह सुनिश्चित करें कि आप जिस subscribe()फ़ंक्शन को पास करते हैं, वह लिंक्ड स्पेक का अनुसरण करता है। लौटी हुई वस्तु की गारंटी एक unsubscribeविधि है जिसे किसी भी संदर्भ को जनरेटर से मुक्त करने के लिए कहा जाना चाहिए (यह वर्तमान में एक RxJs Subscriptionवस्तु है लेकिन यह वास्तव में कार्यान्वयन विवरण है जिस पर निर्भर नहीं होना चाहिए)।

export class MyServiceEvent {
    message: string;
    eventId: number;
}

export class MyService {
    public onChange: EventEmitter<MyServiceEvent> = new EventEmitter<MyServiceEvent>();

    public doSomething(message: string) {
        // do something, then...
        this.onChange.emit({message: message, eventId: 42});
    }
}

export class MyConsumer {
    private _serviceSubscription;

    constructor(private service: MyService) {
        this._serviceSubscription = this.service.onChange.subscribe({
            next: (event: MyServiceEvent) => {
                console.log(`Received message #${event.eventId}: ${event.message}`);
            }
        })
    }

    public consume() {
        // do some stuff, then later...

        this.cleanup();
    }

    private cleanup() {
        this._serviceSubscription.unsubscribe();
    }
}

सभी जोरदार शब्द कयामत और उदासीन भविष्यवाणियां, कोणीय 2 के पूर्व-रिलीज़ संस्करण पर एक एकल डेवलपर से एकल स्टैक ओवरफ्लो टिप्पणी से स्टेम करने के लिए लगती हैं।


2
यह उचित लगता है- कोई और इस पर तौलना चाहता है? सब के बाद एक घटना emitter पर सदस्यता एक सार्वजनिक तरीका है?
शॉनसन

ठीक है, यह सार्वजनिक है इसलिए हम इसका उपयोग करने के लिए स्वतंत्र हैं। लेकिन क्या इस उदाहरण में EventEmitter over Observable का उपयोग करने का कोई व्यावहारिक कारण है?
बोटिस

6
अब हम Angular v6 पर हैं और EventEmmiter को निकाला नहीं गया या हटाया नहीं गया, इसलिए मैं कहूंगा कि इसका उपयोग करना सुरक्षित है। हालाँकि, मैं RxJS से वेधशालाओं का उपयोग करने के तरीके सीखने के लाभ देखता हूँ।
डेविड मेजा

मैं इसे "अगर आप @Output के बाहर EventEmitter का उपयोग कर रहे हैं, तो इसे किसी और चीज़ में बदलने की ज़रूरत नहीं है क्योंकि यह api ATM है;" यदि आपके पास समय है या एपीआई टूटता है, तो आपको इसे बदलना होगा (लेकिन ध्यान रखें कि कोणीय के लिए सार्वजनिक स्थिर एपीआई बदलने के लिए (उत्सर्जन और सदस्यता) आम नहीं है)। सार्वजनिक एपी से भी चिपके रहें, सब्जेक्ट या ऑब्जर्वेबल के उन तरीकों तक न पहुँचें जो ईवेंटइंटरटर में सुरक्षित साइड पर रहने के लिए परिभाषित नहीं हैं
acidghost

1
यह धारणा कि "कोणीय से हटाए नहीं" या "अच्छी तरह से प्रलेखित" होने के कारण कुछ उपयोग करने के लिए सुरक्षित है, गलत है और साथ ही ऊपर प्रस्तावित नॉन पॉलिसी भी। आप कोणीय के भविष्य के संस्करणों के कारण नहीं एक परियोजना बनाते हैं। वहाँ बहुत सारे नहीं मंच से बाहर वहाँ अभी भी वेब पर काम कर रहे हैं। फ्रेमवर्क का संस्करण उन डेवलपर्स को नहीं बनाता है जो उन प्लेटफार्मों पर काम कर रहे थे जो डेवलपर्स या बी श्रेणी के डेवलपर्स से कम थे।
क्लाउडियो फेरारो

4

जब आप क्रॉस कंपोनेंट इंटरैक्शन करना चाहते हैं, तो आपको यह जानना होगा कि @Input, @Output, EventEmitter और Subjects क्या हैं।

यदि घटकों के बीच संबंध माता-पिता या बच्चे के विपरीत है तो हम घटना emitter के साथ @input & @output का उपयोग करते हैं ..

@output किसी ईवेंट का उत्सर्जन करता है और आपको ईवेंट एमिटर का उपयोग करके उत्सर्जन करना होगा।

यदि यह अभिभावक बाल संबंध नहीं है .. तो आपको विषयों का उपयोग करना होगा या एक सामान्य सेवा के माध्यम से।


0

कोई नहीं है: नोनो और नहीं: यस। सच्चाई मध्य में है और कोणीय के अगले संस्करण के कारण डरने की कोई वजह नहीं है।

तार्किक दृष्टिकोण से, यदि आपके पास एक घटक है और आप अन्य घटकों को सूचित करना चाहते हैं कि कुछ होता है, तो एक घटना को निकाल दिया जाना चाहिए और यह उस तरीके से किया जा सकता है जैसा कि आप (डेवलपर) को लगता है कि यह किया जाना चाहिए। मैं इसका उपयोग नहीं करने का कारण नहीं देखता हूं और मुझे हर कीमत पर इसका उपयोग करने का कारण नहीं दिखता है। साथ ही EventEmitter नाम मुझे होने वाली घटना के बारे में बताता है। मैं आमतौर पर घटक में होने वाली महत्वपूर्ण घटनाओं के लिए इसका उपयोग करता हूं। मैं सेवा बनाता हूँ, लेकिन घटक फ़ोल्डर के अंदर सेवा फ़ाइल बनाता हूँ। इसलिए मेरी सेवा फ़ाइल इवेंट मैनेजर या इवेंट इंटरफ़ेस का एक प्रकार बन जाती है, इसलिए मैं यह पता लगा सकता हूं कि मैं किस घटक पर वर्तमान घटक की सदस्यता ले सकता हूं।

मुझे पता है। मुझे लगता है मैं एक पुराने जमाने के डेवलपर हूँ। लेकिन यह इवेंट ड्रिवेन डेवलपमेंट पैटर्न का हिस्सा नहीं है, यह आपके विशेष प्रोजेक्ट के सॉफ़्टवेयर आर्किटेक्चर निर्णयों का हिस्सा है।

कुछ अन्य लोग सोच सकते हैं कि वेधशालाओं का उपयोग सीधे ठंडा है। उस मामले में सीधे वेधशालाओं के साथ आगे बढ़ते हैं। आप ऐसा करने वाले सीरियल किलर नहीं हैं। जब तक आप एक मनोरोगी डेवलपर नहीं होते हैं, अब तक कार्यक्रम काम करता है, इसे करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.