簡體   English   中英

在p:datatable中找不到PrimeFaces / JSF組件ID

[英]PrimeFaces/JSF component ID not found from within p:datatable

我剛開始使用PrimeFaces 3.3.1從RichFaces 3和4開始。

我有一個結構的數據表:

            <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>

然而PrimeFaces引發了一個例外:

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]

無法找到該ID。 嗯....我基本上從RichFaces復制了結構。 刪除或編輯行的行按鈕不需要:employee-form:...前綴。 我想知道為什么。

給表單一個ID並在PF組件引用前加上':'語法時,代碼按預期運行:

    <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>

問:

為什么ap:datatable需要在根JSF ID前加上? 也許這是我的代碼,但發布的示例對我來說似乎很少。 在任何情況下,使用它將導致整個應用程序可能存在長ID。

我究竟做錯了什么?

PS:我在JBoss AS 7.1.1.Final,Mojarra 2.1.7,PF 3.3.1

PrimeFaces使用UIComponent#findComponent()提供的標准JSF算法來按給定的客戶端ID查找組件。 該算法在前面提到的javadoc中有詳細描述。 這是相關的摘錄:

搜索表達式由一個標識符(與UIComponent的id屬性完全匹配,或者由UINamingContainer#getSeparatorChar字符值鏈接的一系列此類標識符)組成。搜索算法應按如下方式運行,但可以使用替代算法只要最終結果是相同的:

  • 通過在滿足以下條件之一時立即停止來標識將成為搜索基礎的UIComponent
    • 如果搜索表達式以分隔符開頭(稱為“絕對”搜索表達式),則base將是組件樹的根UIComponent 將剝離前導分隔符,並將搜索表達式的其余部分視為“相對”搜索表達式,如下所述。
    • 否則,如果此UIComponentNamingContainer ,它將作為基礎。
    • 否則,搜索此組件的父級。 如果遇到NamingContainer ,它將是基礎。
    • 否則(如果沒有遇到NamingContainer ),根UIComponent將成為基礎。
  • 搜索表達式(可能在上一步中修改)現在是一個“相對”搜索表達式,用於在基本組件的范圍內定位具有匹配id的組件(如果有)。 比賽按如下方式進行:
    • 如果搜索表達式是一個簡單的標識符,則將此值與id屬性進行比較,然后遞歸通過基本UIComponent的facets和子UIComponent (除非找到后代NamingContainer ,否則不搜索其自己的facet和子節點)。
    • 如果搜索表達式包含由分隔符分隔的多個標識符,則第一個標識符用於通過上一個項目符號點中的規則定位NamingContainer 然后,將調用此NamingContainerfindComponent()方法,傳遞搜索表達式的其余部分。

RichFaces使用相同的算法“有一些額外的例外”

“reRender”使用UIComponent.findComponent()算法(帶有一些額外的例外)來查找組件樹中的組件。

這些額外的例外情況沒有詳細描述,但眾所周知,相關組件ID(即那些不以:開頭的)不僅在最近的父NamingContainer的上下文中搜索,而且還在同一視圖中的所有其他NamingContainer組件中搜索(順便說一句,這是一項相對昂貴的工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM