2016-07-06 17 views
13

में इवेंट प्रतिनिधिमंडल मैं एनजी 2 में एक ऐप विकसित कर रहा हूं और मैं कुछ के साथ संघर्ष कर रहा हूं। मैं एक कैलेंडर बना रहा हूं जहां आप डेट-रेंज चुन सकते हैं और मुझे दिन की कोशिकाओं पर click & mouseenter/mouseleave ईवेंट पर प्रतिक्रिया करने की आवश्यकता है। तो मैं इस तरह एक कोड (सरलीकृत) है:एंगुलर 2

calendar.component.html

<month> 
    <day *ngFor="let day of days" (click)="handleClick()" 
     (mouseenter)="handleMouseEnter()" 
     (mouseleave)="handleMouseLeave()" 
     [innerHTML]="day"></day> 
</month> 

लेकिन यह मेरे ब्राउज़र की स्मृति में अलग घटना श्रोताओं के सैकड़ों देता है (प्रत्येक दिन के सेल 3 घटना श्रोताओं हो जाता है , और मेरे पास एक समय में 12 महीने तक प्रदर्शित हो सकते हैं, इसलिए यह श्रोताओं के 1k से अधिक होगा)।

तो मैं "घटना प्रतिनिधिमंडल" नामक विधि का उपयोग करके इसे "उचित तरीका" करना चाहता था। मेरा मतलब है, पैरेंट घटक (month) पर एक क्लिक ईवेंट संलग्न करें और जब इसे एक क्लिक ईवेंट प्राप्त होता है, तो बस यह जांचें कि यह Day घटक पर हुआ है - और केवल तभी मैं इस क्लिक पर प्रतिक्रिया दूंगा। जब आप इसे selector पैरामीटर पास करते हैं तो jQuery की तरह कुछ on() method में करता है।

लेकिन मैं इसे हैंडलर के कोड में मूल रूप से डोम तत्वों का हवाला कर रहा था:

month.component.ts

private handleClick(event) { 
    if (event.target.tagName === 'DAY') { 
     // handle day click 
    } else { 
     // handle other cases 
    } 
} 

और मेरे साथियों मेरा विचार को अस्वीकार कर दिया है, क्योंकि - के रूप में उन्होंने कहा कि - "एनजी 2 में इसे संभालने का एक आसान, उचित तरीका होना चाहिए; जैसे कि jQuery में है। इसके अलावा, यह यहां नियंत्रण से बाहर हो रहा है - आप महीने के कोड में दिन के क्लिक पर प्रतिक्रिया दे रहे हैं।"

तो, मेरा सवाल है, क्या कोई बेहतर तरीका है? या क्या मैं ऐसी समस्या को हल करने की कोशिश कर रहा हूं जिसे मुझे अब हल करने से परेशान नहीं होना चाहिए, क्योंकि उपयोगकर्ताओं के डिवाइस प्रतिदिन अधिक से अधिक स्मृति/प्रसंस्करण शक्ति प्राप्त करते हैं?

अग्रिम धन्यवाद!

+1

स्टैंडअलोन मॉड्यूल जो इस संभालती हैं। मुझे बहुत अच्छी तरह से काम करने के लिए "डोम-प्रतिनिधि" मिलते हैं। जहां तक ​​मुझे पता है ng2 में अंतर्निहित कुछ भी नहीं है। – Chrillewoodz

+1

यदि यह एक मुद्दा है ... यह कोणीय में अनुकूलन समस्या होगी। आपको अनुकूलित करने के लिए घटनाओं को एकत्रित करने के बारे में चिंता करने की ज़रूरत नहीं है। –

+1

मुझे कुछ महीनों पहले एक ही समस्या थी, जो मुझे पता है, आपके द्वारा वर्णित विधि कच्चे कोणीय के साथ ऐसा करने का सबसे अच्छा तरीका है। कम घटना श्रोताओं के साथ क्लिक लक्ष्यों की जांच। एकमात्र चीज जो मैं सुझाऊंगा वह एक सेवा या निर्देश में तर्क डाल रहा है (निर्देश प्रत्येक महीने div पर इसे बेहतर तरीके से काम कर सकता है) जिस तरह से कोड साफ़ और घटक से अलग होता है। आखिरकार, यह एचटीएमएल तर्क है, घटक तर्क – FussinHussin

उत्तर

1

पहचान

मैं आज भर में ठोकर खाई है, और मैं वास्तव में आवेदनों की एक बहुत में इस कार्यान्वयन के लिए की जरूरत देख सकते हैं। अब मैं यह नहीं कह सकता कि यह 100% सर्वश्रेष्ठ तकनीक है, हालांकि मैं इस दृष्टिकोण को यथासंभव प्रेरित कोणीय के रूप में बनाने के लिए अपने रास्ते से बाहर चला गया हूं।

जिस दृष्टिकोण के साथ मैं आया हूं उसके पास 2 चरण हैं। चरण 1 और चरण 2 दोनों में कुल years * months + years * months * days जोड़ दिया जाएगा, इसलिए 1 वर्ष के लिए आपके पास 12 + 365 ईवेंट होंगे।


स्टेज स्कोप

चरण 1: जब एक महीने वास्तविक दिन में नीचे क्लिक होने के प्रतिनिधि किसी घटना के समय दिन पर एक घटना की आवश्यकता के बिना क्लिक किए गए।
चरण 2: चुने हुए दिन को महीने में प्रचारित करें।

बस में जाने पर पहले, आवेदन 3 घटकों जो निम्न क्रम में नेस्टेड रहते हैं के होते हैं: app => month => day


यह सब एचटीएमएल कि आवश्यक है। एप्लिकेशन।घटक कई महीनों होस्ट करता है, month.component कई दिनों होस्ट करता है और day.component कुछ भी नहीं करता है लेकिन इसे दिन के रूप में प्रदर्शित करता है।

app.component.html

<app-month *ngFor="let month of months" [data-month]="month"></app-month> 

month.component.html

<app-day *ngFor="let day of days" [data-day]="day">{{day}}</app-day> 

day.component.html

<ng-content></ng-content> 

यह सुंदर स्टॉक मानक सामान है।


चरण 1

के month.component.ts पर एक नजर है, जहां हम से हमारे घटना को सौंपने के लिए चाहते हैं।

// obtain a reference to the month(this) element 
constructor(private element: ElementRef) { } 

// when this component is clicked... 
@HostListener('click', ['$event']) 
public onMonthClick(event) { 
    // check to see whether the target element was a child or if it was in-fact this element 
    if (event.target != this.element.nativeElement) { 
    // if it was a child, then delegate our event to it. 
    // this is a little bit of javascript trickery where we are going to dispatch a custom event named 'delegateclick' on the target. 
    event.target.dispatchEvent(new CustomEvent('delegateEvent')); 
    } 
} 

दोनों चरण 1 और 2, वहाँ केवल 1 चेतावनी है और वह है, अगर आप अपने day.component.html के भीतर बच्चे तत्वों नेस्ट है, तो आप या तो इस के लिए बुदबुदाती लागू करने के लिए, बेहतर तर्क है कि में अगर बयान, की आवश्यकता होगी या एक त्वरित हैक में day.component.css:host *{pointer-events: none;}


अब हम हमारी बताने की आवश्यकता होगी .. day.component हमारी delegateEvent घटना की अपेक्षा करने के लिए। day.component.ts तुम सब करने की है (सबसे कोणीय तरीका संभव में) में तो ...

@HostListener('delegateEvent', ['$event']) 
public onEvent() { 
    console.log("i've been clicked via a delegate!"); 
} 

यह काम करता है क्योंकि टाइपप्रति या नहीं के बारे में है कि क्या घटना निवासी है परवाह नहीं है, यह सिर्फ एक नया बाँध होगा तत्व के लिए जावास्क्रिप्ट घटना और इस प्रकार हम इसे event.target.dispatchEvent के माध्यम से "मूल रूप से" कॉल करने की अनुमति देते हैं क्योंकि हम ऊपर month.component.ts में करते हैं।

यह चरण 1 का निष्कर्ष निकाला है, अब हम अपने महीने से हमारे दिनों तक घटनाओं को सफलतापूर्वक प्रतिनिधि दे रहे हैं।


स्टेज 2

तो क्या हुआ अगर हम कहते हैं day.component के भीतर हमारे सौंप घटना में तर्क का एक छोटा सा चलाने के लिए और फिर इसे month.component पर वापस आना चाहते होता है - इतना है कि यह तो साथ पर ले जा सकता है इसके एक बहुत ऑब्जेक्ट उन्मुख विधि में अपनी कार्यक्षमता? सौभाग्य से, हम इसे आसानी से कार्यान्वित कर सकते हैं!

month.component.ts में निम्न के लिए अद्यतन करें। जो कुछ बदल गया है वह यह है कि अब हम अपने कार्यक्रम के आमंत्रण के साथ एक समारोह पारित करने जा रहे हैं और हमने अपने कॉलबैक फ़ंक्शन को परिभाषित किया है।

@HostListener('click', ['$event']) 
    public onMonthClick(event) { 
    if (event.target != this.element.nativeElement) { 
     event.target.dispatchEvent(new CustomEvent('delegateEvent', { detail: this.eventDelegateCallback})); 
    } 
    } 

    public eventDelegateCallback(data) { 
    console.log(data); 
    } 

जो कुछ भी बचा है, वह इस कार्य को day.component.ts के भीतर आमंत्रित करना है ...

public onEvent(event) { 
    // run whatever logic you like, 
    //return whatever data you like to month.component 
    event.detail(this.day); 
} 

दुर्भाग्य से हमारे कॉलबैक फ़ंक्शन एक छोटे से अस्पष्ट यहाँ नाम है, लेकिन टाइपप्रति के बारे में संपत्ति यदि अन्यथा नामित CustomEventInit के लिए एक परिभाषित वस्तु शाब्दिक नहीं किया जा रहा शिकायत नहीं है।


एकाधिक घटना कीप

इस दृष्टिकोण के बारे में अन्य अच्छी बात यह है कि आप घटनाओं की इस संख्या से अधिक परिभाषित करने के लिए है क्योंकि आप सिर्फ इस प्रतिनिधिमंडल के माध्यम से सभी घटनाओं फ़नल और फिर तर्क चला सकते हैं कभी नहीं होना चाहिए वह यह है कि day.component.ts भीतर event.type द्वारा फिल्टर करने के लिए ...

month.component.ts

@HostListener('click', ['$event']) 
@HostListener('mouseover', ['$event']) 
@HostListener('mouseout', ['$event']) 
    public onMonthEvent(event) { 
    if (event.target != this.element.nativeElement) { 
     event.target.dispatchEvent(new CustomEvent('delegateEvent', { detail: this.eventDelegateCallback })); 
    } 
    } 

day.component.ts

private eventDelegateCallback: any; 

@HostListener('delegateEvent', ['$event']) 
    public onEvent(event) { 
    this.eventDelegateCallback = event.detail; 
    if(event.type == "click"){ 
     // run click stuff 
     this.eventDelegateCallback(this.day) 
    } 
    } 
+0

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

+0

हालांकि, कई घटनाएं वास्तव में लाभ ला सकती हैं :) –

+0

@MichalLeszczyk यह एन मार्क पर काफी हिट नहीं करता है लेकिन यह एक महत्वपूर्ण सुधार है और जब आप एक नया ईवेंट प्रकार जोड़ते हैं तो भी तेजी से वृद्धि नहीं होती है। यह सही नहीं है, लेकिन मुझे लगता है कि यह सही रास्ते पर है! – Zze