Primefaces selectOneMenu不显示初始值

时间:2015-07-30 08:46:42

标签: jsf primefaces selectonemenu

我在p:dialog中设置了带有POJO和转换器的selectOneMenu,请参阅下面的来源。它 工作,除了最初,当它首次以非下拉状态显示时,选择第一个选项,而不是与bean值相对应的选择。如果我保存selectOneMenu的状态而根本不与它交互,则保存最初选择的第一个选项,因此覆盖实际值,但如果我选择了一个不同的选项,则会正确保存。 selectOneMenu绑定到的bean值不能是null

我调试了转换器,事实证明,当加载后备数据并刷新并显示对话框时,所有选项都通过转换器的getAsString()加上真实bean值的选择再次。仍然,第一个选择实际上被选中并显示在selectOneMenu中。当提交对话框的表单时,实际选择的选项将通过转换器的getAsObject(),无论是错误选择的初始值还是手动选择的初始值。

请告知可能出现的问题。

调用对话框的按钮的xhtml,其形式不同:

<p:commandButton id="toolbarEditButton" 
            value="Edit selected" update=":editMediaForm"
            disabled="#{!contentManager.mediaSelected}"
            actionListener="#{contentManager.editSelectedMedia}"
            onclick="PF('editMediaWidget').show()" />

对话框的xhtml:

    <p:dialog id="editMediaDialog" widgetVar="editMediaWidget"
        modal="true" resizable="false" >
        <h:form id="editMediaForm" >
            <p:panelGrid rendered="#{contentManager.isMediaSelected()}" columns="2" >
                ... <!-- other properties of the selected element -->
                <p:outputLabel value="Media type" />
                <p:selectOneMenu value="#{contentManager.selectedMedia.mediaType}"
                                 converter="#{mediaTypeConverter}">
                    <f:selectItems value="#{mediaTypeConverter.allMediaTypes}"
                        var="mt" itemLabel="#{mt.name}" itemValue="#{mt}" />
                    <p:ajax listener="#{contentManager.onMediaTypeChanged()}" />
                </p:selectOneMenu>
            </p:panelGrid>
        </h:form>
    </p:dialog>

转换器:

@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String stringId) {
    Long id = Long.valueOf(stringId);
    for (MediaType mt : mediaTypes) {
        if (mt.getPkid().equals(id)) {
            return mt;
        }
    }
    return null;
}

@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object mtObj) {
    MediaType mt = (MediaType) mtObj;
    return mt.getPkid().toString();
}

public List<MediaType> getAllMediaTypes() {
    return mediaTypes;
}

编辑:支持bean

@SessionScoped // javax.enterprise.context.SessionScoped
@Named("contentManager") // javax.inject.Named
public class ContentManager implements Serializable {
    ...
    private List<Media> mediaList;
    private Media selectedMedia = null;
    ...
    public boolean isMediaSelected() {
        if (selectedMedia == null) return false;
        return true;
    }
    ...
    public void saveSelectedMedia() {
        myDao.saveMedia(selectedMedia);
    }

    public void editSelectedMedia() {
        // only for debugging, could be removed
    }
}

启动对话框并通过编辑按钮更新表单,该按钮仅在从dataTable(selectedMedia)中选择元素后才可用。更新确实有效,因为所选元素的其他属性已正确更新并显示在对话框中,因此selectOneMenu背后的bean值应该没问题。

更新:当然我还检查了生成的HTML。 <select>对我来说似乎没问题,它包含转换器要转换的正确值。 (选择仍然是错误的)

<select id="form:blah_input" name="form:blah_input" tabindex="-1">
    <option value="1" selected="selected">1 - half_horizontal</option>
    <option value="2">2 - half_vertical</option>
    <!-- etc -->
</select>

1 个答案:

答案 0 :(得分:3)

SelectOneMenu中显示的对象必须具有正确的equals()方法,而不仅仅是默认的Object#equals,只有当它们是同一个对象时才是真的。这解释了为什么初始显示值始终是第一个:bean值从未与任何可能的值匹配,因此SelectOneMenu组件只显示第一个。

所以错误不在于JSF或支持bean代码,而在于显示的域对象&#39; (MediaType)代码。添加equals()方法解决了这个问题。