Primefaces更新<p:column>仅渲染子组件致布局错乱问题求助
问题:PrimeFaces嵌套组件Ajax更新后布局异常的解决
在嵌套于<p:dataTable>的<p:panelGrid>中,当同一行内的输入项变更时,需要重新渲染对应的<p:column>以更新其样式类。相关代码如下:
<h:form id="my-form"> <p:dataTable id="my-table" var="item" [...]> <p:column [...]> <p:panelGrid [...]> <p:row id="item-row"> <p:column id="item-question-column" styleClass="#{item.valueSet ? '' : 'value_not_set'}"> <p:outputLabel id="item-question-column-label" value="#{item.questionNumberLabel}" /> </p:column> <p:column> <p:selectOneRadio id="radio" value="#{item.value}"> <f:selectItems var="option" value="#{item.options}" itemLabel="#{option.label}" itemValue="#{option.value}" /> <p:ajax event="change" update="item-question-column" /> </p:selectOneRadio> </p:column> </p:row> </p:panelGrid> </p:column> </p:dataTable> </h:form>
遇到的问题:
- 触发Ajax更新
item-question-column后,该列对应的外层<td>消失,导致布局混乱 - 若更新整个
item-row,渲染正常但会重新渲染单选框,使绑定在jQuery.ready()上的 onChange 代码失效
使用环境:PrimeFaces 10 + Mojarra 2.4.0
解决方案
使用*<h:panelGroup>或<p:outputPanel>*作为item-question-column内部的包装容器,将样式类和Ajax更新目标转移到这个容器上,避免直接更新<p:column>导致的TD丢失问题。
修改后的代码示例:
<h:form id="my-form"> <p:dataTable id="my-table" var="item" [...]> <p:column [...]> <p:panelGrid [...]> <p:row id="item-row"> <p:column id="item-question-column"> <!-- 用panelGroup作为包装容器,设置styleClass并作为Ajax更新目标 --> <h:panelGroup id="question-wrapper" styleClass="#{item.valueSet ? '' : 'value_not_set'}"> <p:outputLabel id="item-question-column-label" value="#{item.questionNumberLabel}" /> </h:panelGroup> </p:column> <p:column> <p:selectOneRadio id="radio" value="#{item.value}"> <f:selectItems var="option" value="#{item.options}" itemLabel="#{option.label}" itemValue="#{option.value}" /> <!-- 更新包装容器而非直接更新column --> <p:ajax event="change" update="question-wrapper" /> </p:selectOneRadio> </p:column> </p:row> </p:panelGrid> </p:column> </p:dataTable> </h:form>
关键说明:
<h:panelGroup>默认渲染为行内元素<span>,若需要块级元素可添加layout="block"属性,不破坏原有布局<p:outputPanel>功能与<h:panelGroup>类似,同样可作为容器使用,在PrimeFaces 10中兼容性良好- 直接更新
<p:column>会导致PrimeFaces在Ajax渲染时无法正确重建外层的<td>标签,而更新内部容器组件则会保留原有的<td>结构,避免布局混乱 - 此方式不会重新渲染单选框,因此绑定在
jQuery.ready()上的代码不会失效
内容的提问来源于stack exchange,提问作者Janus Engstrøm
相关产品推荐
相关产品推荐

