【问题标题】:Primefaces SelectOneMenu doesn't update default valuePrimefaces SelectOneMenu 不更新默认值
【发布时间】:2014-09-03 02:15:20
【问题描述】:

我有一个单一选择的数据表。选择一行并按下按钮后,将打开输入文本和选择一个菜单的对话框。输入文本和一个菜单应包含所选行的数据。一般来说,它是一个用于编辑数据表中记录的对话框。 但是在对话框中选择一个菜单不会根据所选行更改默认值。它适用于<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>

【问题讨论】:

  • SpecimenType 类上有 equals() 和 hashCode() 吗?
  • @JaqenH'ghar 感谢您的回复。 SpecimenType 是一个数据模型类,包含带有 getter 和 setter 的属性。我应该覆盖equals() 和hashCode() 方法吗?
  • I am not sure but I think its a requirement.. when selectmenus gives problems its typically caused by either this or the converter.有关实施,请参见 BalusC 的答案:stackoverflow.com/questions/10726716/…
  • @JaqenH'ghar 太棒了,它正在工作。你能回答我的问题吗?我愿意接受您的解决方案。
  • 谢谢,很高兴它成功了

标签: jsf-2 primefaces selectonemenu


【解决方案1】:

当 SelectOneMenu 和类似组件无法按预期工作时,应检查转换器并确保实体/pojo 上有 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 可以为空,则需要在这些方法中使用更多字段。也可以使用 Apache Commons/Lang HashCodeBuilder 和 EqualsBuilder,如答案 here 中所述。

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

【讨论】:

    【解决方案2】:

    另一个可能的原因可能是(如其他帖子中所述 - 我只是将其包含在此处以帮助尚未找到它的其他人)selectOneMenu 显示的对象列表在调用 RowEditEvent 侦听器。

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

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

    再次,为这个非常烦人且有些晦涩的问题添加另一种可能的解决方案。向 PrincAm 和 JaqenH'ghar 致敬,感谢他们将帖子作为对他人的宝贵资源。

    【讨论】:

      猜你喜欢
      • 2014-03-21
      • 2013-11-30
      • 2013-08-14
      • 2015-05-04
      • 2012-10-03
      • 1970-01-01
      • 1970-01-01
      • 2015-11-05
      • 2023-03-11
      相关资源
      最近更新 更多