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;
public void ajaxListener(AjaxBehaviorEvent event) {
System.out.println(value);
}
इसके अलावा, यदि आपको प्रस्तुत मूल्य के आधार पर किसी अन्य संपत्ति को अपडेट करने की आवश्यकता है , तो यह तब विफल हो जाएगा जब आप उपयोग कर रहे हैं 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));
}
logger.trace( "setting changeTypes from {} to {}", this.changeTypes, changeTypes );