2012-08-07 12 views
6

मैं सिर्फ RichFaces 3 और 4PrimeFaces/JSF घटक आईडी पी के भीतर से नहीं मिला: datatable

से आ रही PrimeFaces 3.3.1 के साथ शुरू कर रहा हूँ मैं संरचना के साथ एक datatable है:

  <f:facet name="header"> 
       <h:outputText value="Employees" /> 
      </f:facet> 

      <p:column sortBy="#{emp.lastName}"> 
       <f:facet name="header"> 
        <h:outputText value="Last Name" /> 
       </f:facet> 
       <h:outputText value="#{emp.lastName}" /> 
      </p:column> 

      <p:column> 
       <f:facet name="header"> 
        <h:outputText value="First Name" /> 
       </f:facet> 
       <h:outputText value="#{emp.firstName}" /> 
      </p:column> 

      ... 

      <p:column> 
        <p:commandButton icon="ui-icon ui-icon-trash" 
            value="Remove" 
            process="@this" 
            update="employee-remove-dialog" 
            oncomplete="employeeRemoveDialog.show();"> 
         <f:setPropertyActionListener target="#{employeeManager.currentEmployee}" value="#{emp}" /> 
        </p:commandButton> 
      </p:column> 
     </p:dataTable> 

     <p:dialog header="Remove Employee" 
        modal="true" 
        appendToBody="true" 
        widgetVar="employeeRemoveDialog" 
        id="employee-remove-dialog"> 
      <h:outputText value="Remove employee #{employeeManager.currentEmployee.fullName}?" /> 
      <f:facet name="footer"> 
       <p:commandButton icon="ui-icon ui-icon-check" 
           value="OK" 
           action="#{employeeManager.deleteEmployee}" 
           process="@this" 
           update="employee-list" 
           oncomplete="employeeRemoveDialog.hide();" /> 
       <p:commandButton icon="ui-icon ui-icon-close" 
           value="Cancel" 
           onclick="employeeRemoveDialog.hide();" 
           ajax="false" 
           immediate="true" /> 
      </f:facet> 
     </p:dialog> 

    </h:form> 

09:36:08,961 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-localhost-127.0.0.1-8080-1) Error Rendering View[/employeeList.xhtml]: javax.faces.FacesException: Cannot find component with identifier "employee-remove-dialog" referenced from "j_idt30:employee-list:0:j_idt41". 
    at org.primefaces.util.ComponentUtils.findClientIds(ComponentUtils.java:251) [primefaces-3.3.1.jar:] 
    at org.primefaces.util.AjaxRequestBuilder.addIds(AjaxRequestBuilder.java:102) [primefaces-3.3.1.jar:] 
    at org.primefaces.util.AjaxRequestBuilder.update(AjaxRequestBuilder.java:90) [primefaces-3.3.1.jar:] 
    at org.primefaces.renderkit.CoreRenderer.buildAjaxRequest(CoreRenderer.java:195) [primefaces-3.3.1.jar:] 
    at org.primefaces.component.commandbutton.CommandButtonRenderer.encodeMarkup(CommandButtonRenderer.java:74) [primefaces-3.3.1.jar:] 
    at org.primefaces.component.commandbutton.CommandButtonRenderer.encodeEnd(CommandButtonRenderer.java:49) [primefaces-3.3.1.jar:] 
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:312) [jsf-impl-2.1.7-jbossorg-2.jar:] 
    at com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185) [jsf-impl-2.1.7-jbossorg-2.jar:] 
    at com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:129) [jsf-impl-2.1.7-jbossorg-2.jar:] 
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at org.primefaces.component.datatable.DataTableRenderer.encodeRegularCell(DataTableRenderer.java:780) [primefaces-3.3.1.jar:] 
    at org.primefaces.component.datatable.DataTableRenderer.encodeRow(DataTableRenderer.java:741) [primefaces-3.3.1.jar:] 
    at org.primefaces.component.datatable.DataTableRenderer.encodeTbody(DataTableRenderer.java:645) [primefaces-3.3.1.jar:] 
    at org.primefaces.component.datatable.DataTableRenderer.encodeRegularTable(DataTableRenderer.java:248) [primefaces-3.3.1.jar:] 
    at org.primefaces.component.datatable.DataTableRenderer.encodeMarkup(DataTableRenderer.java:220) [primefaces-3.3.1.jar:] 
    at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:107) [primefaces-3.3.1.jar:] 
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1786) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at javax.faces.render.Renderer.encodeChildren(Renderer.java:168) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:55) [primefaces-3.3.1.jar:] 
    at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43) [primefaces-3.3.1.jar:] 
    at org.primefaces.component.layout.LayoutUnitRenderer.encodeEnd(LayoutUnitRenderer.java:51) [primefaces-3.3.1.jar:] 
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1786) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402) [jsf-impl-2.1.7-jbossorg-2.jar:] 
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125) [jsf-impl-2.1.7-jbossorg-2.jar:] 
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121) [jsf-impl-2.1.7-jbossorg-2.jar:] 
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.7-jbossorg-2.jar:] 
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) [jsf-impl-2.1.7-jbossorg-2.jar:] 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:] 
    at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31] 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:] 
    at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final] 
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final] 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:] 
    at java.lang.Thread.run(Unknown Source) [rt.jar:1.7.0_04] 

आईडी नहीं पाया जा सकता है:

हालांकि PrimeFaces एक अपवाद फेंकता है। हम्म .... मैंने मूल रूप से रिचफेस से संरचना की प्रतिलिपि बनाई। पंक्ति को हटाने या संपादित करने के लिए पंक्ति बटन की आवश्यकता नहीं है: कर्मचारी-फॉर्म: ... उपसर्ग। मुझे आश्चर्य है क्यों।

जब प्रपत्र एक आईडी दे रही है और साथ पीएफ घटक संदर्भ लगाकर ':' वाक्य रचना कोड चलाता है के रूप में उम्मीद:

<h:form id="employee-form"> 
     <p:dataTable ...> 
      ... 
      <p:column> 
       <h:panelGrid ...> 
        <p:commandButton ... 
            update=":employee-form:employee-remove-dialog" 
            ...> 
         ... 
        </p:commandButton> 
       </h:panelGrid> 
      </p:column> 
     </p:dataTable> 
     <p:dialog ... 
        id="employee-remove-dialog"> 
     </p:dialog> 
    </h:form> 

प्रश्न:

क्यों एपी: datatable जरूरत रूट जेएसएफ आईडी को उपसर्ग करने के लिए? शायद यह मेरा कोड है, लेकिन पोस्ट किया गया उदाहरण मेरे लिए न्यूनतम लगता है। किसी भी मामले में, इसका उपयोग करने से परिणामस्वरूप पूरे आवेदन में संभवतः लंबी आईडी हो जाएगी।

मैं क्या गलत कर रहा हूं?

पुनश्च: मैं JBoss 7.1.1.Final, Mojarra 2.1.7, पीएफ 3.3.1

उत्तर

13

PrimeFaces के रूप में पर हूँ मानक JSF एल्गोरिथ्म के रूप में दिए गए ग्राहक आईडी के आधार पर घटकों को खोजने के लिए UIComponent#findComponent() द्वारा प्रदान का उपयोग करता है। एल्गोरिदम को विस्तार से जवाडोक में वर्णित विस्तार से बताया गया है। यहाँ प्रासंगिकता के एक उद्धरण है:।

एक खोज अभिव्यक्ति (या तो एक पहचानकर्ता के होते हैं जो वास्तव में एक UIComponent की आईडी संपत्ति, या UINamingContainer#getSeparatorChar चरित्र मूल्य से जुड़े इस तरह के पहचानकर्ता की एक श्रृंखला के खिलाफ मिलान किया जाता है खोज एल्गोरिथ्म चाहिए इस प्रकार है, हालांकि वैकल्पिक alogrithms अंतिम परिणाम के रूप में लंबे समय के लिए इस्तेमाल किया जा सकता है संचालित एक ही है:

  • UIComponent कि खोज, जैसे ही निम्न स्थितियों में से एक है के रूप में रोक कर के लिए आधार हो जाएगा पहचानें मिले:
    • यदि खोज अभिव्यक्ति विभाजक चरित्र (जिसे "पूर्ण" खोज अभिव्यक्ति कहा जाता है) से शुरू होता है, तो बेस घटक पेड़ के रूट UIComponent होगा। अग्रणी विभाजक चरित्र को हटा दिया जाएगा, और शेष खोज अभिव्यक्ति को नीचे वर्णित "रिश्तेदार" खोज अभिव्यक्ति के रूप में माना जाएगा।
    • अन्यथा, यदि यह UIComponentNamingContainer है तो यह आधार के रूप में कार्य करेगा।
    • अन्यथा, इस घटक के माता-पिता को खोजें। यदि NamingContainer का सामना करना पड़ता है, तो यह आधार होगा।
    • अन्यथा (यदि NamingContainer का सामना नहीं किया गया है) रूट UIComponent आधार होगा।
  • खोज अभिव्यक्ति (संभवतः पिछले चरण में संशोधित) अब एक "रिश्तेदार" खोज अभिव्यक्ति है कि (यदि हो तो) घटक पता लगाने के लिए एक आईडी से मेल खाता है है कि इस्तेमाल किया जाएगा, आधार के दायरे के भीतर है घटक। खोज अभिव्यक्ति एक सरल पहचानकर्ता है
    • तो यह मान आईडी संपत्ति की तुलना में है, और फिर रिकर्सिवली पहलुओं और आधार UIComponent के बच्चों के माध्यम से (सिवाय एक वंशज NamingContainer है अगर है कि: मैच के रूप में निम्नानुसार किया जाता है पाया, अपने स्वयं के पहलू और बच्चों की खोज नहीं की जाती है)।
    • यदि खोज अभिव्यक्ति में विभाजक चरित्र से अलग एक से अधिक पहचानकर्ता शामिल हैं, तो पहले पहचानकर्ता को पिछले बुलेट बिंदु के नियमों द्वारा NamingContainer का पता लगाने के लिए उपयोग किया जाता है। फिर, इस NamingContainer की findComponent() विधि को खोज अभिव्यक्ति के शेष को पारित करने के लिए बुलाया जाएगा।

RichFaces एक ही एल्गोरिथ्म "with some additional exceptions" उपयोग करता है।

"rerender"UIComponent.findComponent() एल्गोरिथ्म (कुछ अतिरिक्त अपवादों को छोड़कर) का उपयोग करता घटक पेड़ में घटक खोजने के लिए।

उन अतिरिक्त अपवाद विस्तार से कहीं वर्णित हैं, लेकिन यह अच्छी तरह से है कि रिश्तेदार घटक आईडी में जाना जाता है (यानी : के साथ शुरू नहीं होता है) केवल निकटतम माता पिता NamingContainer के संदर्भ में की खोज नहीं कर रहे हैं, लेकिन यह भी अन्य सभी NamingContainer में एक ही दृश्य में घटक (जो कि रास्ते में अपेक्षाकृत महंगा नौकरी है)।

+3

(+1) एल्गोरिदम पोस्ट करने के लिए धन्यवाद: यह एक ठोस मामले के लिए ठोस से अधिक मददगार है। – Ralph

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