You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Primefaces中Dialog内SelectOneMenu Converter无法正常显示值的问题

Primefaces 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未显示对应选中值,显示效果如下:
Dialog显示异常


解决思路

  1. 移除p:resetInput标签:触发按钮中的<p:resetInput>会重置Dialog内组件值,直接覆盖busquedaMb.sindicatura.auxOnomastico已设置的选中值,删除该标签即可避免此问题。
  2. 重构Converter匹配逻辑:当前Converter使用hashCode()作为匹配依据,但对象的hashCode()可能在不同实例或序列化场景下不一致。建议改用实体类的唯一标识字段(如ID)实现Converter:
    • 修改serialize方法,返回实体的唯一ID字符串;
    • 修改fromSelect方法,根据ID从listaOnomastico列表中定位对应实体。
  3. 确保下拉列表数据就绪:检查onomasticoMb.listaOnomastico在Dialog更新前是否已正确加载。可在触发按钮的actionListener中提前初始化该列表,或在Dialog的preRender事件中校验数据状态。
  4. 确认渲染条件有效性:Dialog内的<p:outputPanel rendered="#{not empty busquedaMb.sindicatura}" />需确保在组件更新时该条件始终为真,避免因渲染条件不满足导致组件未被正确更新。

内容的提问来源于stack exchange,提问作者Serpados

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 15:30:55