我正在一个小型Web应用程序中使用JSF 2.3和Bootsfaces 3.3。我偶然发现了Bootsfaces的引发异常而
我在xhtml页面上播放以明确实际问题的位置,对我来说,它看起来像
<h:body>
<b:form id="formTable">
<!-- iterate over list of objects -->
<ui:repeat value="#{testBean.list}" var="element">
<b:row>
<b:column><h:outputText id="ajaxUpdateMe" value="#{element.name}" /></b:column>
</b:row>
<b:row>
<b:column>
<!-- iterate over another list -->
<h:dataTable value="#{element.innerList}" var="inner">
<h:column>
<b:commandButton ajax="true" value="submit"
action="#{testBean.submit(element)}"
update=":#{component.namingContainer.parent.namingContainer.clientId}:ajaxUpdateMe"
process="@this" />
</h:column>
</h:dataTable>
</b:column>
</b:row>
</ui:repeat>
</b:form>
</h:body>
[当我尝试通过浏览器访问xhtml页面(GET请求)时,会立即引发一个如下所示的异常(为简洁起见,将其简化):
Caused by: javax.faces.FacesException: Invalid search expression: formTable:j_idt4:0:ajaxUpdateMe The subexpression 0 doesn't exist, or it can't be resolved. net.bootsfaces.component.commandButton.CommandButton formTable:j_idt4:0:j_idt9:0:j_idt13 Additional information: ID not found: 0 search expression: formTable:j_idt4:0:ajaxUpdateMe
at net.bootsfaces.expressions.ExpressionResolver.translateSearchExpressionToId(ExpressionResolver.java:143)
at net.bootsfaces.expressions.ExpressionResolver.getComponentId(ExpressionResolver.java:89)
at net.bootsfaces.expressions.ExpressionResolver.getComponentIDs(ExpressionResolver.java:50)
at net.bootsfaces.expressions.ExpressionResolver.getComponentIDs(ExpressionResolver.java:44)
at net.bootsfaces.component.ajax.AJAXRenderer.generateAJAXCallForClientBehavior(AJAXRenderer.java:582)
at net.bootsfaces.component.ajax.AJAXRenderer.generateBootsFacesAJAXAndJavaScript(AJAXRenderer.java:233)
at net.bootsfaces.component.ajax.AJAXRenderer.generateBootsFacesAJAXAndJavaScript(AJAXRenderer.java:177)
at net.bootsfaces.component.commandButton.CommandButtonRenderer.encodeBegin(CommandButtonRenderer.java:120)
at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:892)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:307)
at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:114)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:918)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:309)
at com.sun.faces.renderkit.html_basic.TableRenderer.renderRow(TableRenderer.java:398)
at com.sun.faces.renderkit.html_basic.TableRenderer.encodeChildren(TableRenderer.java:161)
我在这里用这段代码替换了Bootsfaces的命令按钮:
<h:commandButton value="submit"
action="#{testBean.submit(element)}">
<f:ajax render=":#{component.namingContainer.parent.namingContainer.clientId}:ajaxUpdateMe"
execute="@this"/>
</h:commandButton>
现在页面加载正常,命令按钮将执行应做的工作。在浏览器中检查html页面的源,我可以看到异常消息formTable:j_idt4:0:ajaxUpdateMe
中提到的元素实际上在那里。
我是不是在Bootsfaces中遇到了错误,还是我做错了什么?有人知道一种解决方法,仍然可以从Bootsfaces使用命令按钮吗?
[BootsFaces ID解析器看起来像0
中的formTable:j_idt4:0:ajaxUpdateMe
挣扎。您可以尝试将id="elements
添加到ui:repeat,然后通过:formTable:elements:ajaxUpdateMe
直接引用目标组件。
<h:body> <b:form id="formTable"> <!-- iterate over list of objects --> <ui:repeat id="elements" value="#{testBean.list}" var="element"> <b:row> <b:column><h:outputText id="ajaxUpdateMe" value="#{element.name}" /></b:column> </b:row> <b:row> <b:column> <!-- iterate over another list --> <h:dataTable value="#{element.innerList}" var="inner"> <h:column> <b:commandButton ajax="true" value="submit" action="#{testBean.submit(element)}" update=":#formTable:elements:ajaxUpdateMe" process="@this" /> </h:column> </h:dataTable> </b:column> </b:row> </ui:repeat> </b:form> </h:body>
我的IDE并不建议
ui:repeate
实际上具有id
属性,但是它对我有用。