Primefaces中Dialog内SelectOneMenu Converter无法正常显示值的问题
点击编辑按钮打开Dialog后,Dialog内的SelectOneMenu组件无法正确渲染对应选中值,以下是相关代码片段:
触发按钮代码
<p:column headerText="Editar" styleClass="centrarColumna"> <p:commandButton icon="pi pi-pencil" update=":edicionSindicatura:contenidoEdicionSindicatura" oncomplete="PF('edicionSindicatura').show()" process="@this"> <f:setPropertyActionListener value="#{listadoSI}" target="#{busquedaMb.sindicatura}" /> <p:resetInput target=":edicionSindicatura:contenidoEdicionSindicatura" /> </p:commandButton> </p:column>
Dialog 代码
<?xml version="1.0" encoding="UTF-8"?> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui" > <h:form id="edicionSindicatura"> <p:dialog header="Edición de Datos" showEffect="fade" modal="true" responsive="true" widgetVar="edicionSindicatura"> <p:outputPanel id="contenidoEdicionSindicatura"> <p:outputPanel rendered="#{not empty busquedaMb.sindicatura}"> <div class="ui-fluid"> <h:panelGrid columns="2" layout="grid" styleClass="ui-panelgrid-blank ui-fluid"> <h:panelGroup> ...... </h:panelGroup> <h:panelGroup> <p:outputLabel value="#{mens.edicionSindicaturaOnomasticos}"/> <p:selectOneMenu id="onomastico" value="#{busquedaMb.sindicatura.auxOnomastico}" converter="selectOneMenuConverter" autoWidth="false"> <f:selectItem itemLabel="--Elegir Onomástico--" itemValue=""/> <f:selectItems value="#{onomasticoMb.listaOnomastico}" var="lista" itemLabel="#{lista.descripcion}" itemValue="#{lista}"/> </p:selectOneMenu> </h:panelGroup> ..... </h:panelGrid> </div> </p:outputPanel> </p:outputPanel> <f:facet name="footer"> <p:commandButton value="Guardar" icon="pi pi-check" actionListener="#{busquedaMb.guardarSindicatura()}" update="contenidoEdicionSindicatura" process="contenidoEdicionSindicatura @this" /> <p:commandButton value="Cancel" icon="pi pi-times" onclick="PF('edicionSindicatura').hide()" type="button" /> </f:facet> </p:dialog> </h:form> </ui:composition>
Converter 代码
package es.cortes.archivoCortes.view.converter; import java.util.List; import javax.faces.component.UIComponent; import javax.faces.component.UISelectItem; import javax.faces.component.UISelectItems; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.convert.FacesConverter; /** * The Class SelectOneMenuConverter. */ @FacesConverter("selectOneMenuConverter") public class SelectOneMenuConverter implements Converter { @Override public Object getAsObject(final FacesContext arg0, final UIComponent arg1, final String objectString) { if (objectString == null) { return null; } return fromSelect(arg1, objectString); } /** * Serialize. * * @param object * the object * @return the string */ private String serialize(final Object object) { if (object == null) { return null; } return object.getClass() + "@" + object.hashCode(); } /** * From select. * * @param currentcomponent * the currentcomponent * @param objectString * the object string * @return the object */ private Object fromSelect(final UIComponent currentcomponent, final String objectString) { if (currentcomponent.getClass() == UISelectItem.class) { final UISelectItem item = (UISelectItem) currentcomponent; final Object value = item.getValue(); if (objectString.equals(serialize(value))) { return value; } } if (currentcomponent.getClass() == UISelectItems.class) { final UISelectItems items = (UISelectItems) currentcomponent; final List<Object> elements = (List<Object>) items.getValue(); for (final Object element : elements) { if (objectString.equals(serialize(element))) { return element; } } } if (!currentcomponent.getChildren().isEmpty()) { for (final UIComponent component : currentcomponent.getChildren()) { final Object result = fromSelect(component, objectString); if (result != null) { return result; } } } return null; } @Override public String getAsString(final FacesContext arg0, final UIComponent arg1, final Object object) { return serialize(object); } }
问题现象
点击按钮打开Dialog后,SelectOneMenu未显示对应选中值,显示效果如下:
解决思路
- 移除
p:resetInput标签:触发按钮中的<p:resetInput>会重置Dialog内组件值,直接覆盖busquedaMb.sindicatura.auxOnomastico已设置的选中值,删除该标签即可避免此问题。 - 重构Converter匹配逻辑:当前Converter使用
hashCode()作为匹配依据,但对象的hashCode()可能在不同实例或序列化场景下不一致。建议改用实体类的唯一标识字段(如ID)实现Converter:- 修改
serialize方法,返回实体的唯一ID字符串; - 修改
fromSelect方法,根据ID从listaOnomastico列表中定位对应实体。
- 修改
- 确保下拉列表数据就绪:检查
onomasticoMb.listaOnomastico在Dialog更新前是否已正确加载。可在触发按钮的actionListener中提前初始化该列表,或在Dialog的preRender事件中校验数据状态。 - 确认渲染条件有效性:Dialog内的
<p:outputPanel rendered="#{not empty busquedaMb.sindicatura}" />需确保在组件更新时该条件始终为真,避免因渲染条件不满足导致组件未被正确更新。
内容的提问来源于stack exchange,提问作者Serpados
相关产品推荐
相关产品推荐

