使用OmniFacesSelectItemsConverter在HtmlSelectOneMenu中动态预选项目



我想动态创建一个包含所有可能选项的下拉列表(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,我将CategorytoString()方法更改为:

@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;
  }

如果我设置了menu.setConverter(new SelectItemsConverter());,则预选了错误的项目。但是,如果我删除它,那么会选择正确的项目,但当我尝试保存表单时,它失败了,因为它没有下拉列表的转换器。

有人能帮我吗?我已经在GitHub上发布了代码。方法createDropdown可以在链接代码的底部找到。

您的错误就在这里,在String.class类型参数中:

ValueExpression valueExpression = JSFUtils.createValueExpression(jsfValue, String.class);

Category不是String。改用Category.class,一切都会好起来。至少在理论上是这样。如果不进行更改,我就无法复制、粘贴或运行这段代码。

我在代码中发现了错误。简单地说,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;
}

相关内容

  • 没有找到相关文章

最新更新