2012-05-23 13 views
5

मेरे जेएसएफ 2 आधारित एप्लिकेशन में मेरे पास एक ऐसा फॉर्म है जिसमें कुछ अन्य चेकबॉक्स शामिल हैं।सत्यापन त्रुटि के बाद बाद में AJAX अनुरोध UI घटक से मान प्राप्त करते हैं, बीन्स

चेकबॉक्स पर मैंने AJAX अनुरोध पंजीकृत किए हैं, जब वे चेक किए जाते हैं। AJAX अनुरोध वास्तव में बैकिंग बीन में किसी अन्य चेकबॉक्स के मान को अपडेट करेंगे। नतीजतन अन्य चेकबॉक्स भी चेक किए जाएंगे (जब इसे फिर से प्रस्तुत किया जाता है - क्योंकि यह प्रतिक्रिया प्रतिक्रिया चरण में बैकिंग बीन से अद्यतन मूल्य ले जाएगा)।

यह तब तक ठीक काम करता है जब तक पूरा फॉर्म सबमिट नहीं हो जाता है और सत्यापन त्रुटियां होती हैं। फिर AJAX अनुरोध बैकिंग बीन पर मान को काम करते हैं और बदलते हैं लेकिन अपडेट किए गए चेकबॉक्स को फिर से प्रस्तुत करने के चरण में इसके लिए मान बैकिंग बीन से नहीं लिया जाता है, लेकिन ComponentStateHelper कक्षा से लिया गया कैश वैल्यू से लिया जाता है।

जहां तक ​​मैं समझता हूं कि इसका उपयोग जेएसएफ 2 की नई सुविधा के लिए केवल घटक पेड़ में आंशिक परिवर्तनों को संग्रहीत करने के लिए किया जाता है।

जो मुझे समझ में नहीं आता है यह है: यह सत्यापन चरण से कैसे संबंधित है? प्रमाणीकरण त्रुटियों के दौरान मेरे चेकबॉक्स के लिए StateHelper कक्षा में कैश किए गए मान क्यों हैं?

उत्तर

4

यह एक ज्ञात समस्या है और this answer में गहराई में समझाया गया है। संक्षेप में, समस्या इसलिए होती है क्योंकि अमान्य घटक जिन्हें <f:ajax render> द्वारा प्रस्तुत किया जाना है, लेकिन <f:ajax execute> द्वारा निष्पादित नहीं किया गया है, मूल सबमिट मूल्य के साथ एक अमान्य स्थिति में बनी हुई है। जब जेएसएफ इनपुट घटक प्रस्तुत करता है, तो जेएसएफ पहले जांच करेगा कि सबमिट किया गया मान null नहीं है और फिर इसे प्रदर्शित करें, अन्यथा यह मॉडल मान प्रदर्शित करेगा। आपको मूल रूप से इनपुट घटकों के सबमिट किए गए मान को रीसेट करने की आवश्यकता होती है जिन्हें प्रस्तुत किया जाना है, लेकिन जिन्हें AJAX द्वारा निष्पादित नहीं किया गया है।

इस लक्ष्य को हासिल करने के लिए, आप एक ActionListener जो मूल रूप से निम्नलिखित करता है का उपयोग कर सकते हैं:

UIViewRoot viewRoot = context.getViewRoot(); 
PartialViewContext partialViewContext = facesContext.getPartialViewContext(); 
Set<EditableValueHolder> inputs = new HashSet<EditableValueHolder>(); 

// First find all to be rendered inputs and add them to the set. 
findAndAddEditableValueHolders(partialViewContext.getRenderIds(), inputs); 

// Then find all executed inputs and remove them from the set. 
findAndRemoveEditableValueHolders(partialViewContext.getExecuteIds(), inputs); 

// The set now contains inputs which are to be rendered, but which are not been executed. Reset them. 
for (EditableValueHolder input : inputs) { 
    input.resetValue(); 
} 

यह JSF issue 1060 के रूप में सूचित किया गया है और एक पूर्ण और reuseable समाधान ResetInputAjaxActionListener रूप OmniFaces पुस्तकालय में लागू किया गया है (स्रोत कोड here और शोकेस डेमो here)।

+0

आपके उत्तर के लिए बहुत बहुत धन्यवाद। मैं पहले से ही अपने प्रोजेक्ट में अपनी सर्वव्यापी lib को शामिल कर चुका था ('FullAjaxExceptionHandlerFactory' के लिए)। इसलिए मेरी 'चेहरे-config.xml' फ़ाइल में' ResetInputAjaxActionListener' को शामिल करना आसान था। लेकिन इसे केवल 'InvokeAplicationPhase' में बुलाया जाता है जो मेरे AJAX अनुरोध द्वारा नहीं मारा जाता है। मेरा AJAX अनुरोध '' द्वारा ट्रिगर किया गया है और वहां ' 'द्वारा किया गया है। लेकिन मैं इस पर एक नज़र डालेगा। मैंने बस आपके सुझाव की जल्दी कोशिश की। – Jens

+0

यह हिट नहीं है? क्या आपको यकीन है? चेहरे-कॉन्फ़िगरेशन को संपादित करने के बाद आपको सर्वर को पुनरारंभ करने की आवश्यकता हो सकती है। – BalusC

+0

मैंने इसे पुनरारंभ किया और मैंने omnifaces का स्रोत जोड़ा और यह देखने के लिए ब्रेकपॉइंट सेट किया कि यह बिल्कुल हिट हो जाता है या नहीं। यह नियमित अनुरोधों पर हिट हो जाता है लेकिन अजाक्स अनुरोध पर नहीं जो चेकबॉक्स के चयन से ट्रिगर होता है। – Jens

संबंधित मुद्दे