我是facelets的新手,我已经使用netbeans生成了一个项目,但我很难使用标签。
我有
<h:selectOneMenu id="country" value="#{organisation.organisation.country}" title="Country" >
<f:selectItems value="#{country.countryItemsAvailableSelectOne}"/>
</h:selectOneMenu>
在select中,我得到类路径。我能看到的Country[iso=GB]是一个对象,但我真的想看到Country.prinableName值。我看了半天都没看到感谢您的帮助
既然您谈论的是Facelets,我假设JSF 2.x.
首先,HTML是一个完整的字符串。JSF生成HTML。默认情况下,非String
Java对象通过toString()
方法转换为它们的String
表示,而JSF生成HTML。要在这些Java对象和String
之间正确转换,需要一个Converter
。
我假设您的Country
对象已经正确实现了equals()
方法,否则验证稍后将失败,并显示"验证错误:值无效",因为所选对象在测试任何可用项的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
类有两个属性code
和name
。我假设接收所选国家/地区的托管bean具有private Country country
属性。在<f:selectItems>
中,您需要在#{data.countries}
上循环,并将country对象指定为项目值,将country名称指定为项目标签。
<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()
中,您实现了将唯一的HTMLString表示转换回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中注册它,JSF将在遇到Country
类型的值表达式时自动使用它。最终,国家代码作为商品价值,国家名称作为商品标签。JSF将在表单提交时将提交的国家代码转换回一个完整的Country
对象。
在JSF 1.x中,原理没有太大区别。在这个博客中,你可以找到两个基本的启动示例:h:selectOneMenu
中的对象。
发生了什么,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;
}
关于CCD_ 31。如果您想直接使用一个特殊的对象,例如一个名为Price
的对象,则必须使用转换器。这里展示了一个例子。
如果在中添加editable="true"
<h:selectOneMenu value="#{bean.country}">
然后,您将在转换器方法中获得一个意外的String
值(不是来自getAsString()
(:
public Object getAsObject(FacesContext context, UIComponent component, String value) { }