2012-08-16 9 views
8

मैं आदेश सशर्त कुछ कार्रवाई के आधार पर पेज टुकड़े रेंडर करने के लिए मेरे webapp में कई स्थानों पर निर्माण निम्नलिखित:छोड़ें <ui:include> क्रियान्वित जब जनक UI घटक गाया नहीं है

<h:panelGroup rendered="#{managedBean.serviceSelected == 'insurance'}"> 
    <ui:include src="/pages/edocket/include/service1.xhtml" /> 
</h:panelGroup> 

मैंने देखा है, कि <ui:include>rendered विशेषता false का मूल्यांकन करने पर भी तब भी निष्पादित की जाती है। यह अनावश्यक रूप से service1.xhtml फ़ाइल से जुड़े सभी बैकिंग बीन्स बनाता है जो शामिल किया गया है।

जब माता-पिता UI घटक प्रदान नहीं किया जाता है तो मैं <ui:include> निष्पादित कैसे कर सकता हूं, ताकि उन सभी समर्थित बीन्स अनावश्यक रूप से बनाए गए न हों?

उत्तर

9

दुर्भाग्यवश, यह डिज़ाइन द्वारा है। दृश्य निर्माण समय के दौरान <ui:include> टैगहेडलर के रूप में चलता है, जबकि rendered विशेषता का मूल्यांकन समय प्रस्तुत करने के दौरान किया जाता है। यह बेहतर ध्यान के साथ "<ui:include>" इस जवाब को पढ़ने और प्रतिस्थापन "JSTL" द्वारा समझा जा सकता:

  1. उपयोग की दृष्टि: JSTL in JSF2 Facelets... makes sense?

    इस को हल करने के कई तरीके, ठोस कार्यात्मक आवश्यकता के आधार पर कर रहे हैं <h:panelGroup> के बजाय <c:if> जैसे समय टैग बनाएं। हालांकि यह #{managedBean} में प्रभाव डालता है। इसे स्कॉप्ड नहीं देखा जा सकता है और HTTP अनुरोध पैरामीटर के आधार पर अपना काम करना चाहिए। वास्तव में उन HTTP अनुरोध पैरामीटर को बाद के अनुरोध में भी रखा जाना चाहिए (उदा। <f:param>, includeViewParams, आदि) ताकि दृश्य को पुनर्स्थापित किए जाने पर यह तोड़ न सके।

  2. एक कस्टम UIComponent जो UIComponent#encodechildren() विधि दौरान FaceletContext#includeFacelet() invokes द्वारा <ui:include> बदलें। मौजूदा पुस्तकालयों में से अब तक कोई ऐसा घटक मौजूद नहीं है। लेकिन मैं यह बता सकता हूं कि OmniFaces के लिए भविष्य में इसके अतिरिक्त के रूप में मैं पहले से ही इस तरह के दिमाग में हूं और यह मेरे परीक्षण पर्यावरण (मोजाररा के साथ) में सहजता से अपेक्षित काम करता है। यहाँ एक किकऑफ़ उदाहरण है:

    @FacesComponent(Include.COMPONENT_TYPE) 
    public class Include extends UIComponentBase { 
    
        public static final String COMPONENT_TYPE = "com.example.Include"; 
        public static final String COMPONENT_FAMILY = "com.example.Output"; 
    
        private enum PropertyKeys { 
         src; 
        } 
    
        @Override 
        public String getFamily() { 
         return COMPONENT_FAMILY; 
        } 
    
        @Override 
        public boolean getRendersChildren() { 
         return true; 
        } 
    
        @Override 
        public void encodeChildren(FacesContext context) throws IOException { 
         getChildren().clear(); 
         FaceletContext faceletContext = ((FaceletContext) context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY)); 
         faceletContext.includeFacelet(this, getSrc()); 
         super.encodeChildren(context); 
        } 
    
        public String getSrc() { 
         return (String) getStateHelper().eval(PropertyKeys.src); 
        } 
    
        public void setSrc(String src) { 
         getStateHelper().put(PropertyKeys.src, src); 
        } 
    
    } 
    
+0

हाय, जबाब BaluSC के लिए धन्यवाद: src शामिल हैं। लेकिन मैं जवाब को समझने में सक्षम नहीं हूं। जहां हमें इस घटक को घोषित करने और इसका उपयोग करने की आवश्यकता है। –

+0

हाय बलुस्क, घटक जोड़ने के बाद शामिल करने की पूरी तरह से हो रहा है। लेकिन जब इसे शामिल करने की आवश्यकता होती है, तो वह समय विफल रहता है। मैं एफवाईआई अपवाद पेस्ट करूँगा। –

+0

क्या यह अभी तक omnifaces में शामिल किया गया है, BalusC? –

6

उपयोग ui के रूप में सशर्त अभिव्यक्ति:

<h:panelGroup> 
    <ui:include 
     src="#{managedBean.serviceSelected == 'insurance' ? 
      '/pages/edocket/include/service1.xhtml' 
      : 
      '/pages/empty.xhtml'}" 
    /> 
</h:panelGroup> 
संबंधित मुद्दे