在我们的应用程序中,我们有各种选择字段。 select字段的内容始终使用数据库中的值填充,例如currency
选择器将包含数据库中添加的货币,或User
可能会根据某些用户的角色选择对象。
现在,问题是此数据可能会随着时间的推移而发生变化,但使用此值的旧实例应保持不变。如果某个用户现在已被选为leadDeveloper
,由于他的角色,但他离开了公司,则选择列表不再包含该用户,因此选择字段现在将显示无选择选项,因为列表源不再包含该元素。
有没有一种好方法可以绕过这个问题?
具体例子:
的java:
@Named
@ViewScoped
public class MyBean{
public List<IKeyValuePair> getAvailableDeveloper(){
// everything available to select-fields is implementing
// iKeyValuePair, most the time used as id/name, depending on entity
return userDataService.getUsersWithRole("developer");
}
}
public class User implements IKeyValuePair{
//properties
@Override
public string getKey(){
//use id
return this.id.toString();
}
@Override
public string getValue(){
//use lastname, firstname
return this.lastname + ", " + this.firstname;
}
}
XHTML:
<p:selectOneMenu value="#{project.leadDeveloper}" style="width:125px" readonly="#{project.closed}">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{myBean.availableDevelopers}" var="dev"
itemLabel="#{dev.getValue()}" itemValue="#{dev.getKey()}" />
</p:selectOneMenu>
现在,用户将从该列表中选择 - 让我们说 alice 。从现在开始,该项目的历史视图将在项目结束后将 alice 显示为已禁用的selectOneMenu中的选定开发人员。
2年后,alice离开了公司,因此她的角色开发人员已被撤销。 getAvailableDeveloper()
将不再包含alice
,因此所选值不再是数据源的一部分 - 现在,选择字段将显示选择一个。
我可以手动确保将相关用户添加到列表中以用于历史记录(如果缺少) - 但是这需要我在相应的getter中实现 case-by-case -method,取决于实体类型。
如果可以在selectOneMenu的(自定义)渲染器内以自动方式处理它会更好。但在我这样做之前,我想询问是否有关于这个主题的最佳实践解决方案。
ps:代码不是精确的副本,只是一个概述问题的快速示例。
答案 0 :(得分:0)
我终于通过代理方法调用每个人getter
来解决它,该代理方法负责剩下的工作。
而不是
public List<IKeyValuePair> getAvailableDeveloper(){
// everything available to select-fields is implementing
// iKeyValuePair, most the time used as id/name, depending on entity
return userDataService.getUsersWithRole("developer");
}
以及标记
<f:selectItems value="#{myBean.availableDevelopers}" var="dev"
itemLabel="#{dev.getValue()}" itemValue="#{dev.getKey()}" />
我最终调用了一个“通用”方法,传递当前选择和实际List,最后将此选择添加到返回列表中,如果不存在:
<f:selectItems value="#{myBean.proxyForLists(myBean.availableDevelopers, currentElement)}" var="dev"
itemLabel="#{dev.getValue()}" itemValue="#{dev.getKey()}" />
和代理方法
public List<IKeyValuePair> proxyForLists(List<IKeyValuePair> source, Object selection){
if (selection == null) return source;
if (selection instanceof User){
User selectedUser = (User) selection;
KeyValuePair kvp = new KeyValuePair(selectedUser.getShortName(), selectedUser);
if (!source.contains(kvp)){
source.add(kvp);
}
}
//other types handled as well.
return source;
}
因此,只要选定的值A
不再是源列表的一部分,就会通过代理方法添加它,使选择字段能够再次显示它。对于“新”创作,A
不再是源列表的一部分,因此用户无法再选择A
。