2011-09-08 59 views
2

我是facelets的新手,我使用netbeans生成了一個項目,但是我在標籤上掙扎。F:selectItems顯示類不是值

<h:selectOneMenu id="country" value="#{organisation.organisation.country}" title="Country" > 
       <f:selectItems value="#{country.countryItemsAvailableSelectOne}"/> 
      </h:selectOneMenu> 

在選擇我得到classpath.Country [ISO = GB]我可以看到的是一個對象,但我真的想看到的country.prinableName值。 我看這半天,並繪製一個空白 感謝所有幫助

回答

0

你怎麼了,selectOneMenu呼籲所有給定對象toString()方法。

您必須使用selectitems或簡單的converter來管理它。一個非常簡單的例子:

price.xhtml:

<h:selectOneMenu id="priceMenu" value="#{priceBean.selectedPrice}"> 
    <f:selectItems value="#{priceBean.prices}" /> 
</h:selectOneMenu> 

PriceBean.java:

.. 
private String selectedPrice; 
.. 
public String getSelectedPrice() { 
    return selectedPrice; 
} 

public void setSelectedPrice(String newPrice) { 
    selectedPrice = newPrice; 
} 
.. 
public List<SelectItem> getPrices() { 
    List<SelectItem> retVal = new ArrayList<SelectItem>(); 

    retVal.add(new SelectItem("2")); 
    retVal.add(new SelectItem("4")); 
    retVal.add(new SelectItem("6")); 

    return retVal; 
} 

有關SelectItem進一步信息。如果您想直接使用特定對象,例如名爲Price的對象,則必須使用轉換器。 Here an example is shownand here

5

由於您在談論Facelets,我將假設JSF 2.x.

首先,HTML是一個和所有的字符串。 JSF生成HTML。默認情況下,當JSF生成HTML時,非String Java對象被toString()方法轉換爲其String表示。要正確地在這些Java對象和String之間進行轉換,您需要一個Converter

我假設你Country對象已具有equals()方法properly implemented,否則驗證稍後將會失敗「驗證錯誤:值無效」,因爲所選擇的對象不針對任何可用項目的測試equals()返回true

因爲#{country}是一個令人困惑的託管bean名稱,所以我在命名上也會做一些改動,因爲它顯然不代表Country類的一個實例。我將其稱爲Data,它應該可以保存應用程序範圍的數據。

@ManagedBean 
@ApplicaitionScoped 
public class Data { 

    private static final List<Country> COUNTRIES = populateItSomehow(); 

    public List<Country> getCountries() { 
     return COUNTRIES; 
    } 

    // ... 
} 

我會假設Country類有兩個屬性codename。我假設接收選定國家的託管bean有一個private Country country屬性。在您的<f:selectItems>中,您需要遍歷#{data.countries}並將國家/地區對象指定爲項目值,將國家/地區名稱指定爲項目標籤。

<h:selectOneMenu value="#{bean.country}"> 
    <f:selectItems value="#{data.countries}" var="country" itemValue="#{country}" itemLabel="#{country.name}" /> 
</h:selectOneMenu> 

現在,你需要爲Country類創建Converter。我們將根據每個國家/地區獨有的國家代碼進行轉換(對嗎?)。在getAsString()中,實現了將Java對象轉換爲在HTML中使用的唯一字符串表示形式的代碼。在getAsObject()中,實現了將唯一HTML字符串表示轉換回Java對象的代碼。

@FacesConverter(forClass=Country.class) 
public class CountryConverter implements Converter { 

    @Override 
    public String getAsString(FacesContext context, UIComponent component, Object value) { 
     return (value instanceof Country) ? ((Country) value).getCode() : null; 
    } 

    @Override 
    public Object getAsObject(FacesContext context, UIComponent component, String value) { 
     if (value == null) { 
      return null; 
     } 

     Data data = context.getApplication().evaluateExpressionGet(context, "#{data}", Data.class); 

     for (Country country : data.getCountries()) { 
      if (country.getCode().equals(value)) { 
       return country; 
      } 
     } 

     throw new ConverterException(new FacesMessage(String.format("Cannot convert %s to Country", value))); 
    } 

} 

@FacesConverter將在JSF自動註冊它,每當它遇到的Country類型的值表達JSF將自動使用它。最終,你最終將國家代碼作爲項目價值和國家名稱作爲項目標籤。在提交表單時,JSF將把提交的國家代碼轉換回完整的Country對象。

在JSF 1.x中,原理沒有多大區別。在這個博客中,您可以找到兩個基本的開球示例:Objects in h:selectOneMenu

+0

謝謝你所有的假設是否正確和很好的解釋將通過這個例子起作用,它也會幫助我 – user845854

0

如果您在

<h:selectOneMenu value="#{bean.country}"> 

添加editable="true"那麼你將在轉換器的方法獲得意想不到的String值(不是從getAsString()):

public Object getAsObject(FacesContext context, UIComponent component, String value) { }