Ill*_*lep 69 database jsf selectonemenu
我正在创建一个Web应用程序,您必须从DB中读取对象/实体列表并在JSF中填充它<h:selectOneMenu>.我无法对此进行编码.有人可以告诉我该怎么做吗?
我知道如何List<User>从数据库中获取数据.我需要知道的是,如何填充此列表<h:selectOneMenu>.
<h:selectOneMenu value="#{bean.name}">
...?
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
Bal*_*usC 171
根据您的问题历史记录,您使用的是JSF 2.x. 所以,这是一个JSF 2.x目标答案.在JSF 1.x中,您将被迫在丑陋的SelectItem实例中包装项值/标签.幸运的是,在JSF 2.x中不再需要这个.
要直接回答您的问题,只需在bean(post)构造期间使用<f:selectItems>其对数据库保留value的List<T>属性.这是一个基本的启动示例,假设T实际上代表了一个String.
<h:selectOneMenu value="#{bean.name}">
<f:selectItems value="#{bean.names}" />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
同
@ManagedBean
@RequestScoped
public class Bean {
private String name;
private List<String> names;
@EJB
private NameService nameService;
@PostConstruct
public void init() {
names = nameService.list();
}
// ... (getters, setters, etc)
}
Run Code Online (Sandbox Code Playgroud)
就那么简单.实际上,T's' toString()将用于表示下拉项标签和值.因此,当您不List<String>使用复杂对象列表而List<SomeEntity>没有覆盖类的toString()方法时,您会看到com.example.SomeEntity@hashcode项目值.请参阅下一节如何正确解决它.
另请注意,bean的<f:selectItems>值不一定需要与bean的bean相同<h:selectOneMenu>.每当值实际上是应用程序范围的常量时,这非常有用,您只需在应用程序启动期间加载一次.然后,您可以将其设置为应用程序范围bean的属性.
<h:selectOneMenu value="#{bean.name}">
<f:selectItems value="#{data.names}" />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
只要T关注一个复杂的对象(一个JavaBean),如User其中有一个String财产name,那么你可以使用var属性来获取迭代变量的保持,你又可以在使用itemValue和/或itemLabelattribtues(如果省略itemLabel,那么label变得与值相同).
示例#1:
<h:selectOneMenu value="#{bean.userName}">
<f:selectItems value="#{bean.users}" var="user" itemValue="#{user.name}" />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
同
private String userName;
private List<User> users;
@EJB
private UserService userService;
@PostConstruct
public void init() {
users = userService.list();
}
// ... (getters, setters, etc)
Run Code Online (Sandbox Code Playgroud)
或者当它具有您希望设置为项值的Long属性时id:
示例#2:
<h:selectOneMenu value="#{bean.userId}">
<f:selectItems value="#{bean.users}" var="user" itemValue="#{user.id}" itemLabel="#{user.name}" />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
同
private Long userId;
private List<User> users;
// ... (the same as in previous bean example)
Run Code Online (Sandbox Code Playgroud)
无论何时你想将它设置T为bean中的属性并T表示一个属性User,那么你需要烘焙一个自定义的Converter转换User和一个唯一的字符串表示(可以是id属性).请注意,itemValue必须表示复杂对象本身,正好是需要设置为选择组件的类型value.
<h:selectOneMenu value="#{bean.user}" converter="#{userConverter}">
<f:selectItems value="#{bean.users}" var="user" itemValue="#{user}" itemLabel="#{user.name}" />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
同
private User user;
private List<User> users;
// ... (the same as in previous bean example)
Run Code Online (Sandbox Code Playgroud)
和
@ManagedBean
@RequestScoped
public class UserConverter implements Converter {
@EJB
private UserService userService;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
if (submittedValue == null || submittedValue.isEmpty()) {
return null;
}
try {
return userService.find(Long.valueOf(submittedValue));
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage(String.format("%s is not a valid User ID", submittedValue)), e);
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
if (modelValue == null) {
return "";
}
if (modelValue instanceof User) {
return String.valueOf(((User) modelValue).getId());
} else {
throw new ConverterException(new FacesMessage(String.format("%s is not a valid User", modelValue)), e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
(请注意,Converter为了能够注入@EJBJSF转换器,有点hacky ;通常会注释它@FacesConverter(forClass=User.class),但遗憾的是不允许@EJB注入)
不要忘记,以确保复杂的对象类equals()和hashCode()正确实施,否则,JSF将在呈现无法显示预选项目(S),你会在提交脸验证错误:值无效.
public class User {
private Long id;
@Override
public boolean equals(Object other) {
return (other != null && getClass() == other.getClass() && id != null)
? id.equals(((User) other).id)
: (other == this);
}
@Override
public int hashCode() {
return (id != null)
? (getClass().hashCode() + id.hashCode())
: super.hashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
回答这个问题:为使用Java Generics的实体实现转换器.
JSF实用程序库OmniFaces提供了一个特殊的转换器,允许您使用复杂的对象,<h:selectOneMenu>而无需创建自定义转换器.将SelectItemsConverter只会做基于转换现成的项目<f:selectItem(s)>.
<h:selectOneMenu value="#{bean.user}" converter="omnifaces.SelectItemsConverter">
<f:selectItems value="#{bean.users}" var="user" itemValue="#{user}" itemLabel="#{user.name}" />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
查看页
<h:selectOneMenu id="selectOneCB" value="#{page.selectedName}">
<f:selectItems value="#{page.names}"/>
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
支持bean
List<SelectItem> names = new ArrayList<SelectItem>();
//-- Populate list from database
names.add(new SelectItem(valueObject,"label"));
//-- setter/getter accessor methods for list
Run Code Online (Sandbox Code Playgroud)
要显示特定的选定记录,它必须是列表中的值之一.
| 归档时间: |
|
| 查看次数: |
138762 次 |
| 最近记录: |