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