कब प्रयोग करें ValueChangeListener या f: ajax श्रोता?


87

listenerप्लेसमेंट के संबंध में निम्नलिखित दो कोड के बीच क्या अंतर है ?

<h:selectOneMenu ...>
    <f:selectItems ... />
    <f:ajax listener="#{bean.listener}" />
</h:selectOneMenu>

तथा

<h:selectOneMenu ... valueChangeListener="#{bean.listener}">
    <f:selectItems ... />
</h:selectOneMenu>

जवाबों:


182

valueChangeListenerजब फ़ॉर्म सबमिट किया जाता केवल सक्रिय किया जाएगा और प्रस्तुत मूल्य प्रारंभिक मूल्य से अलग है। यह केवल HTML डोम changeईवेंट को निकाल दिए जाने पर नहीं है। यदि आप HTML DOM changeईवेंट के दौरान फ़ॉर्म सबमिट करना चाहते हैं , तो आपको <f:ajax/>इनपुट कंपोनेंट के बिना श्रोता (!) के साथ एक और जोड़ना होगा । यह एक फॉर्म सबमिट करने का कारण बनेगा जो केवल वर्तमान घटक (जैसे execute="@this") में प्रक्रिया करता है ।

<h:selectOneMenu value="#{bean.value}" valueChangeListener="#{bean.changeListener}">
    <f:selectItems ... />
    <f:ajax />
</h:selectOneMenu>

<f:ajax listener>इसके बजाय का उपयोग करते समय valueChangeListener, यह changeपहले से ही HTML DOM इवेंट के दौरान डिफ़ॉल्ट रूप से निष्पादित होगा । UICommandचेकबॉक्स या रेडियोबॉटन का प्रतिनिधित्व करने वाले घटकों और इनपुट घटकों के अंदर , यह clickकेवल HTML DOM इवेंट के दौरान डिफ़ॉल्ट रूप से निष्पादित किया जाएगा ।

<h:selectOneMenu value="#{bean.value}">
    <f:selectItems ... />
    <f:ajax listener="#{bean.ajaxListener}" />
</h:selectOneMenu>

एक और बड़ा अंतर यह है कि चरण valueChangeListenerके अंत के दौरान विधि को लागू किया जाता है PROCESS_VALIDATIONS। उस समय, प्रस्तुत मूल्य अभी तक मॉडल में अपडेट नहीं किया गया है। इसलिए आप इसे केवल बीन प्रॉपर्टी तक पहुंच कर प्राप्त नहीं कर सकते, जो इनपुट कंपोनेंट के लिए बाध्य है value। आपको इसे प्राप्त करने की आवश्यकता है ValueChangeEvent#getNewValue()। पुराना मूल्य वैसे भी उपलब्ध है ValueChangeEvent#getOldValue()

public void changeListener(ValueChangeEvent event) {
    Object oldValue = event.getOldValue();
    Object newValue = event.getNewValue();
    // ...
}

<f:ajax listener>विधि के दौरान शुरू हो जाती है INVOKE_APPLICATIONचरण। उस समय, प्रस्तुत मूल्य मॉडल में पहले से ही अपडेट किया गया है। आप इसे सीधे बीन संपत्ति तक पहुंच कर प्राप्त कर सकते हैं जो इनपुट घटक के लिए बाध्य है value

private Object value; // +getter+setter.

public void ajaxListener(AjaxBehaviorEvent event) {
    System.out.println(value); // Look, (new) value is already set.
}

इसके अलावा, यदि आपको प्रस्तुत मूल्य के आधार पर किसी अन्य संपत्ति को अपडेट करने की आवश्यकता है , तो यह तब विफल हो जाएगा जब आप उपयोग कर रहे हैं valueChangeListenerक्योंकि अपडेट की गई संपत्ति को बाद के चरण के दौरान जमा किए गए मूल्य से ओवरराइड किया जा सकता है UPDATE_MODEL_VALUES। यही कारण है कि आप पुराने जेएसएफ 1.x अनुप्रयोगों / ट्यूटोरियल / संसाधनों में देखते हैं कि valueChangeListenerइस तरह के निर्माण में एक के साथ संयोजन में immediate="true"और ऐसा होने FacesContext#renderResponse()से रोकने के लिए उपयोग किया जाता है । आखिरकार, valueChangeListenerव्यावसायिक कार्यों को निष्पादित करने के लिए उपयोग करना वास्तव में हमेशा हैक / वर्कअराउंड रहा है।

सारांशित करें: valueChangeListenerयदि आपको वास्तविक मूल्य परिवर्तन पर स्वयं अवरोधन करने की आवश्यकता हो तो ही इसका उपयोग करें । यानी आप वास्तव में रुचि रखते हैं दोनों पुराने और नए मूल्य (जैसे उन्हें प्रवेश करने के लिए)।

public void changeListener(ValueChangeEvent event) {
    changeLogger.log(event.getOldValue(), event.getNewValue());
}

<f:ajax listener>यदि आपको नए बदले गए मूल्य पर व्यावसायिक कार्रवाई निष्पादित करने की आवश्यकता है, तो ही उपयोग करें । यानी आप वास्तव में केवल नए मूल्य (जैसे एक दूसरे ड्रॉपडाउन को पॉप्युलेट करने के लिए) में रुचि रखते हैं ।

public void ajaxListener(AjaxBehaviorEvent event) {
    selectItemsOfSecondDropdown = populateItBasedOn(selectedValueOfFirstDropdown);
}

यदि आप वास्तव में किसी व्यवसाय कार्रवाई को निष्पादित करते समय पुराने मूल्य में रुचि रखते हैं, तो वापस जाएं valueChangeListener, लेकिन इसे INVOKE_APPLICATIONचरण में पंक्तिबद्ध करें ।

public void changeListener(ValueChangeEvent event) {
    if (event.getPhaseId() != PhaseId.INVOKE_APPLICATION) {
        event.setPhaseId(PhaseId.INVOKE_APPLICATION);
        event.queue();
        return;
    }

    Object oldValue = event.getOldValue();
    Object newValue = event.getNewValue();
    System.out.println(newValue.equals(value)); // true
    // ...
}

@ बाल्स्क, क्या कोई कारण है कि इसे पारित होने वाले नए मूल्य पर सेट करने से पहले सेटर में बैकिंग ऑब्जेक्ट से पुराने मूल्य को प्राप्त न करें ? कुछ इस तरह :। ऐसा लगता है कि आप उस फैशन में प्राप्त पुराने और नए मूल्यों का उपयोग सीधे लॉटर में व्यापार तर्क करने के साथ-साथ सरल लॉगिंग के लिए भी कर सकते हैं, लेकिन मुझे नहीं पता कि इससे साइड इफेक्ट होगा या नहीं ...logger.trace( "setting changeTypes from {} to {}", this.changeTypes, changeTypes );
लुकास

बिल्कुल सही और पूरा जवाब! अपनी जानकारी साझा करने के लिए धन्यवाद!
hbobenicio

@ बालसैक क्या यह भी संभव है कि अजाक्सबीहाइवरईवेंट के माध्यम से परिवर्तित मूल्य प्राप्त किया जा सकता है? मेरे पास <h: selectManyListbox है जो अन्य घटकों के लिए जंजीर है और कुछ कार्रवाई करने के लिए परिवर्तित (जोड़ा / हटाया गया) का उपयोग करना पसंद करेंगे
पाउलो जूल


धन्यवाद @BalusC लेकिन मुझे नहीं लगता कि ValueChangeListener मेरे मामले में फिट होगा क्योंकि मेरे पास कुछ निष्पादित और रेंडर मूल्य हैं जैसा कि दिखाया गया है <f: ajax event = "valueChange" "=" परीक्षण "निष्पादित करें" = "इस श्रोता =" # {testController। processTimeTable} "/>
पॉलो

9

पहले टुकड़े के लिए (अजाक्स श्रोता विशेषता):

अजाक्स टैग की "श्रोता" विशेषता एक ऐसी विधि है, जो क्लाइंट साइड पर अजाक्स फ़ंक्शन होने पर हर बार सर्वर पर कॉल की जाती है। उदाहरण के लिए, यदि आप उपयोगकर्ता द्वारा किसी कुंजी को दबाने पर कॉल करने के लिए सर्वर साइड फ़ंक्शन को निर्दिष्ट करने के लिए इस विशेषता का उपयोग कर सकते हैं

लेकिन दूसरा टुकड़ा (valueChangeListener):

ValueChangeListener को केवल तभी बुलाया जाएगा जब फॉर्म सबमिट किया जाता है, तब नहीं जब इनपुट का मूल्य बदल जाता है

* आप इस आसान जवाब को देखना पसंद कर सकते हैं

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