Primefaces SelectOneMenu不会更新默认值

时间:2014-07-12 16:23:21

标签: jsf-2 primefaces selectonemenu

我有一个只有一个选择的数据表。选择一行并按下按钮后,将打开带有输入文本和选择一个菜单的对话框。输入文本和一个菜单应包含所选行的数据。通常,它是一个用于编辑数据表中记录的对话框。 但是,在对话框中选择一个菜单将不会根据所选行更改默认值。它与<h:selectOneMenu>一起使用,但不与Primefaces <p:selectOneMenu>进行扩展。我做错了什么? 我使用的是Primefaces 5.0和JSF 2.1。

XHTML:

<h:form id="form">
    <p:dataTable 
        id="datatable"
        var="spec" 
        value="#{selectionRowAction.specimensBO.list}"
        selection="#{selectionRowAction.selectedSpecimen}"
        selectionMode="single"
        rowKey="#{spec.id}"
        resizableColumns="true">

        <f:facet name="header">
            <p:commandButton id="editButton"
                             process="datatable"
                             update=":form:editPanel" 
                             icon="ui-icon-pencil" 
                             oncomplete="PF('dlg').show()"/>
        </f:facet>  
        <p:column headerText="ID" >
            <h:outputText value="#{spec.subjectIdNumber}" />
        </p:column>
        <p:column headerText="Type" >
            <h:outputText value="#{spec.specimenType.displayText}" />
        </p:column>
    </p:dataTable>

    <p:dialog widgetVar="dlg" >
        <p:outputPanel id="editPanel" >
            <p:panelGrid  columns="2">                  
                <h:outputText value="ID: "/>
                <p:inputText 
                    value="#{selectionRowAction.selectedSpecimen.subjectIdNumber}"/>            
                <h:outputText value="Type: " />
                <p:selectOneMenu 
                    value="#{selectionRowAction.selectedSpecimen.specimenType}" 
                    converter="#{specimenTypeConverter}">
                    <f:selectItem itemLabel="Select One"/>           
                    <f:selectItems value="#{basicSelectionsBO.specimenTypes}" 
                                   var="type" 
                                   itemLabel="#{type.displayText}" 
                                   itemValue="#{type}"/>
                </p:selectOneMenu>
            </p:panelGrid>  
        </p:outputPanel>
    </p:dialog>
</h:form>

2 个答案:

答案 0 :(得分:3)

当SelectOneMenu和类似组件无法按预期工作时,应检查转换器并确保实体/ pojos上有equals()和hashCode()方法。在这种情况下,您缺少两种方法。从BalusC的post复制的简单实现是:

@Override
public boolean equals(Object other) {
    return (other instanceof EntityType) && (id != null)
        ? id.equals(((EntityType) other).id)
        : (other == this);
}

@Override
public int hashCode() {
    return (id != null)
        ? (this.getClass().hashCode() + id.hashCode())
        : super.hashCode();
}

如果id可以为null,则需要在这些方法中使用更多字段。也可以使用Apache Commons / Lang HashCodeBuilder和EqualsBuilder,如答案here中所述。

要验证框架实际调用这些方法,您可以尝试在equals方法中只return true;,这应该始终使SelectOneMenu中的最后一个选项被选中,无论bean中的值如何。使用return false;,它将是第一个选项。

答案 1 :(得分:0)

另一个可能的原因可能是(正如其他帖子中所提到的 - 我只是将其包含在这里以帮助其他尚未找到它的人)selectOneMenu正在显示的对象列表是在/之后/之后重新加载的调用RowEditEvent侦听器。

我有与OP(PrincAm)描述的相同的行为,并且无休止地重构了equals()&amp; hashCode()方法(甚至可以编写尽可能多的单元测试用例来证明它们);等于()&amp; hashCode()方法是正确的,但行为仍然存在。我甚至重构了equals()方法以始终返回true或始终返回false,并且selectOneMenu值将分别设置为第一个菜单选项或最后一个菜单选项。

只有在简要提及重新加载值的可能性之后,我才回过头来看看如何/何时加载该集合;我发现在保存数据表行的action方法中,我会调用一个refresh()方法,该方法重新加载了可选值的集合。一旦我重构我的代码以不重新加载该列表,selectOneMenu将保持按预期选择正确的值。

再次,只是为这个非常烦人且有些模糊的问题添加另一个可能的解决方案。感谢PrincAm&amp; JaqenH'ghar将他们的帖子作为其他人的宝贵资源。