我想动态创建一个包含所有可能选项的下拉列表(HtmlSelectOneMenu)。应预先选择当前设置的选项。为此,我为我的表单创建了一个值表达式:
String jsfValue = String.format("#{%s.item.%s}", getControllerBeanName(), key);
ValueExpression valueExpression = JSFUtils.createValueExpression(jsfValue, String.class);
menu.setValueExpression("value", valueExpression);
字符串#{%s.item.%s}
的计算结果为#{playlistController.item.category}
,而category
是我要绑定到下拉列表的Category
类型的对象。
要使用OmniFaces中的SelectItemsConverter
,我将toString()
的{{1}}方法更改为:
Category
表单生成的代码如下所示(注意:@Override
public String toString() {
return String.format("%s[id=%d]", getClass().getSimpleName(), getId());
}
扩展Category
):
BaseEntity
如果我设置 private UIComponent createDropdown(FormInput property) {
String key = property.getKey();
String beanName = key + "Controller";
GenFormBaseController controller = (GenFormBaseController) JSFUtils.getManagedBean(beanName);
List<BaseEntity> list = controller.getService().findAll();
List<SelectItem> selectItems = new ArrayList<>(list.size());
for (BaseEntity itemInList : list) {
selectItems.add(new SelectItem(itemInList, itemInList.getName()));
}
UISelectItems items = new UISelectItems();
items.setValue(selectItems.toArray());
HtmlSelectOneMenu menu = new HtmlSelectOneMenu();
menu.setConverter(new SelectItemsConverter());
menu.setId(key);
menu.getChildren().add(items);
String jsfValue = String.format("#{%s.item.%s}", getControllerBeanName(), key);
ValueExpression valueExpression = JSFUtils.createValueExpression(jsfValue, String.class);
menu.setValueExpression("value", valueExpression);
return menu;
}
,则会预先选择错误的项目。但是如果我删除它,那么选择了正确的项目,但是当我尝试保存表单时它会失败,因为它没有用于下拉列表的转换器。
任何人都可以帮助我吗?我发布了code on GitHub。
方法menu.setConverter(new SelectItemsConverter());
可以在链接代码的底部找到。
答案 0 :(得分:2)
你的错误在于String.class
类型参数:
ValueExpression valueExpression = JSFUtils.createValueExpression(jsfValue, String.class);
Category
不是String
。请改用Category.class
,一切都应该很好。至少在理论上。我无法复制'n'paste'n'run这段代码而不做任何修改。
答案 1 :(得分:1)
我在代码中发现了错误。简单地说BaseEntity的equals()和hashCode()是不够的。错误BalusC已经提到了。生成的代码如下所示:
GenFormBaseController.java
private UIComponent createDropdown(FormInput property) {
String key = property.getKey();
Class<?> expectedType = property.getValue();
String beanName = lowerFirstChar(expectedType.getSimpleName()) + "Controller";
GenFormBaseController controller = (GenFormBaseController) JSFUtils.getManagedBean(beanName);
List<BaseEntity> list = controller.getService().findAll();
List<SelectItem> selectItems = new ArrayList<>(list.size());
for (BaseEntity itemInList : list) {
selectItems.add(new SelectItem(itemInList, itemInList.getName()));
}
UISelectItems items = new UISelectItems();
items.setValue(selectItems);
HtmlSelectOneMenu menu = new HtmlSelectOneMenu();
menu.setConverter(new SelectItemsConverter());
menu.setId(key);
menu.getChildren().add(items);
String jsfValue = String.format("#{%s.item.%s}", getControllerBeanName(), key);
ValueExpression valueExpression = JSFUtils.createValueExpression(jsfValue, expectedType);
menu.setValueExpression("value", valueExpression);
return menu;
}
BaseEntity.java
@Override
public int hashCode() {
int hash = 7;
hash = 97 * hash + Objects.hashCode(this.id);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final BaseEntity other = (BaseEntity) obj;
if (!Objects.equals(this.id, other.id)) {
return false;
}
return true;
}