2014-07-12 129 views
0

我有一個單一選擇的數據表。選擇一行並按下按鈕後,將顯示帶有輸入文本的對話框並選擇一個菜單。輸入文本和一個菜單應包含所選行的數據。通常,它是一個用於編輯數據表中記錄的對話框。 但是,在對話框中選擇一個菜單將不會更改基於選定行的默認值。它與<h:selectOneMenu>一起使用,但不是從Primefaces <p:selectOneMenu>擴展而來的。我做錯了什麼? 我正在使用Primefaces 5.0和JSF 2.1。Primefaces SelectOneMenu不更新默認值

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> 
+1

你對類SpecimenType有equals()和hashCode()嗎? –

+0

@ JaqenH'ghar感謝您的回覆。 SpecimenType是包含getter和setter屬性的數據模型類。我應該重寫'equals()'和'hashCode()'方法嗎? – PrincAm

+0

我不確定,但我認爲它是一個要求..當selectmenus給出問題時,它通常是由這個或轉換器引起的。對於實現請參閱BalusC的答案在這裏:http://stackoverflow.com/questions/10726716/primefaces-selectonemenu-doesnt-working-when-it-should –

回答

3

當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可以爲空一個需要在這些方法中使用更多的領域。也可以按照答案here中的解釋使用Apache Commons/Lang HashCodeBuilder和EqualsBuilder。

要驗證框架實際調用這些方法,您可以在equals方法中嘗試僅使用return true;,無論bean中的值如何,都應該始終選擇SelectOneMenu中的最後一個選項。與return false;它將是第一個選項。

0

另一個可能的原因可能是(正如其他文章中提到的 - 我只在這裏包括它來幫助尚未找到它的其他人)selectOneMenu顯示的對象列表在/之後立即重新加載RowEditEvent偵聽器被調用。我有和OP(PrincAm)所描述的相同的行爲,並且無休止地重構equals()& hashCode()方法(甚至可以寫出儘可能多的單元測試用例來證明它們)。 equals()& hashCode()方法是正確的,但行爲仍然存在。我甚至重構了equals()方法以始終返回true或始終返回false,selectOneMenu值將分別設置爲第一個菜單選項或最後一個菜單選項。

只有在簡單地提到重新加載值的可能性之後,我纔回過頭去看看該集合是如何/何時加載的;我發現在保存數據錶行的操作方法中,我會調用refresh()方法,重新加載可選值的集合。一旦我重構我的代碼不重新加載該列表,selectOneMenu將保持正確的值按預期方式選擇。

再次,只是添加另一個可能的解決方案,這非常惱人和有點晦澀的問題。榮譽給PrincAm & JaqenH'ghar,因爲他們將他們的信息作爲寶貴的資源提供給其他人。