我试图使用primefaces 5.2创建一个selectOneMenu,列表项是从数据库加载的,它们的类型是一个包含其他属性的Object,我想复制the primefaces showcase method(高级一个) ),但从未分配选定的值,这是我的代码:
<h:form id="f">
<p:selectOneMenu id="advanced" value="#{expertiseController.selectedExpertise}" converter="expertiseConverter">
<f:selectItems value="#{expertiseController.expertises}" var="exp" itemLabel="#{exp.id}" itemValue="#{exp}" />
<p:ajax update="test" />
</p:selectOneMenu>
<p:outputLabel id="test" value="#{expertiseController.selectedExpertise.id}"/>
</h:form>
豆子:
@Named(value = "expertiseController")
@ViewScoped
public class ExpertiseController implements Serializable {
private Expertise selectedExpertise = new Expertise();
private List<Expertise> expertises = Expertise.getAllExpertiseTypes();
....
getters ..
转换器:
FacesConverter("expertiseConverter")
public class ExpertiseConverter implements Converter {
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
if(value != null && value.trim().length() > 0) {
try {
return Expertise.getById(value);
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
else {
return null;
}
}
public String getAsString(FacesContext fc, UIComponent uic, Object object) {
if(object != null) {
return String.valueOf(((Expertise) object).getId());
}
else {
return null;
}
}
}
但是从未设置outputLabel,并且永远不会触发selectedExpertise
的setter方法。
现在这只发生在我将itemValue设置为#{exp}
时,但是当我将它设置为#{exp.id}
(并更改selectOneMenu值)时,一切正常。
我甚至检查了转换器的值,它们都很好。
问题是,当我尝试使用primefaces示例时,它运行良好!当我把它更改为我的对象并转换它dosnt!
我在这里错过了什么或做错了什么?
更新
我只是想通了你必须在转换器中返回列表中的相同对象,这就是我所做的,
我在ExpertiseController
中注入ExpertiseConverter
,然后我循环遍历ExpertiseController
的列表并返回相同的对象(我猜的是相同的地址),这里是代码:
import com.medisecretaire.controller.ExpertiseController;
import com.medisecretaire.model.Expertise;
import java.io.Serializable;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
@FacesConverter("expertiseConverter")
public class ExpertiseConverter implements Converter, Serializable {
@Inject
private ExpertiseController controller;
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
System.out.println(controller.getExpertises());
if(value != null && value.trim().length() > 0) {
try {
for (Expertise expertise : controller.getExpertises()) {
if(expertise.getId().equalsIgnoreCase(value)){
return expertise;
}
}
return null;
} catch(Exception e) {
return null;
}
}
else {
return null;
}
}
public String getAsString(FacesContext fc, UIComponent uic, Object object) {
if(object != null) {
return String.valueOf(((Expertise) object).getId());
}
else {
return null;
}
}
}
但有更好的方法吗?我不喜欢&#34;注射&#34;部分......还是正常的?
更新2:
当我添加filter="true"
时,它不再起作用......这令人困惑......
更新3:
我知道有更好的方法!所以我抓住了UIComponent
提取的SelectOneMenu
迭代了它的子节点并找到UISelectItems
,从那里我发现存储在列表中的相同对象,这里是代码:
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
List list = null;
SelectOneMenu menu = (SelectOneMenu) uic;
for (UIComponent comp : menu.getChildren()) {
if (comp instanceof UISelectItems) {
UISelectItems item = (UISelectItems) comp;
if (item.getValue() instanceof List) {
list = (List) item.getValue();
}
}
}
//Do something with the list
并且现在使用filer属性。