好吧,我需要对selectOneMenu标签做一些澄清,使用EL表达式获取/设置值
<h:selectOneMenu id="variantsMenu"
value="#{missionHandler.selectedVariant}"
converter="#{missionHandler.variantConverter}">
<f:selectItem itemLabel="-- Select a Variant --" />
<f:selectItems value="#{missionHandler.variants}" var="variant"
itemValue="#{variant}" itemLabel="#{variant.commercialName}" />
</h:selectOneMenu>
我有这个代码,它显示一个包含(&#34; - 选择变体 - &#34;,变体1,变体2,...变体n)的列表
当我单击Variant时,我希望selectedVariant
managedBean中的missionHandler
属性能够自动更新。但这种情况并非如此。甚至没有调用variantConverter
转换器来转换String&#34; variant.commercialName&#34;到一个真正的Variant
对象。
变体对象实现hashCode()
和equals()
我的更新问题的解决方案是什么?
编辑: managedBean(简化)
@ManagedBean
@ViewScoped
public class MissionHandler implements Serializable {
private static final long serialVersionUID = 2462652101518266609L;
private List<FlightFeasibilityException> exceptions;
@EJB
private VariantDao variantDao;
private Variant selectedVariant;
private List<Variant> variants;
private VariantConverter variantConverter;
public MissionHandler() {
/** Create an empty list of exceptions */
exceptions = new ArrayList<FlightFeasibilityException>();
}
@PostConstruct
public void init() {
System.out.println("init done");
}
public List<FlightFeasibilityException> getExceptions() {
return exceptions;
}
public void setExceptions(List<FlightFeasibilityException> exceptions) {
this.exceptions = exceptions;
}
public Variant getSelectedVariant() {
return selectedVariant;
}
public void setSelectedVariant(Variant selectedVariant) {
this.selectedVariant = selectedVariant;
}
public List<Variant> getVariants() {
return variants;
}
public void setVariants(List<Variant> variants) {
this.variants = variants;
}
public VariantConverter getVariantConverter() {
return variantConverter;
}
public void setVariantConverter(VariantConverter variantConverter) {
this.variantConverter = variantConverter;
}
}
转换器
@FacesConverter(forClass=Variant.class)
public class VariantConverter implements Converter, Serializable {
private static final long serialVersionUID = 7053414108213420057L;
private VariantDao variantDao=new VariantDaoImpl();
@Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
System.out.println("convert to Object " + value);
Variant variant = variantDao.find(value);
System.out.println("got variant " + variant.getCommercialName());
return variant;
}
@Override
public String getAsString(FacesContext context, UIComponent component,
Object value) {
System.out.println("convert to String " + value);
return ((Variant) value).getCommercialName();
}
}
和xhtml文件
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Mission Page</title>
<link href="./css/styles.css" rel="stylesheet" type="text/css" />
</h:head>
<h:body>
<rich:panel>
<f:facet name="header">
Mission Information
</f:facet>
<a4j:outputPanel layout="block">
<h:form>
<h:outputText style="font-weight: bold;" value="Mission Id: " />
<h:inputText id="missionId" label="missionId"
value="#{missionHandler.mission.id}" disabled="true"
style=" width : 50px;">
</h:inputText>
<h:outputText style="font-weight: bold;" value="Mission Status: " />
<h:inputText id="missionStatus" label="missionStatus"
value="#{missionHandler.mission.status}" disabled="true">
</h:inputText>
</h:form>
<br />
<h:form>
<h:selectOneMenu value="#{missionHandler.selectedAircraftType}"
converter="#{missionHandler.acTypeConverter}">
<f:selectItem itemLabel="-- Select an A/C Type --" />
<f:selectItems value="#{missionHandler.aircraftTypes}" var="type"
itemValue="#{type}" itemLabel="#{type.typeOACI}" />
<f:ajax listener="#{missionHandler.changeSelectedAircraftType}"
render="@form" />
</h:selectOneMenu>
<h:selectOneMenu id="variantsMenu"
value="#{missionHandler.selectedVariant}"
converter="#{missionHandler.variantConverter}"
rendered="#{not empty missionHandler.selectedAircraftType}">
<f:selectItem itemLabel="-- Select a Variant --" />
<f:selectItems value="#{missionHandler.variants}" var="variant"
itemValue="#{variant}" itemLabel="#{variant.commercialName}" />
</h:selectOneMenu>
</h:form>
</a4j:outputPanel>
</rich:panel>
….. A LOT OF OTHER THINGS …..
</h:body>
</html>
答案 0 :(得分:2)
当您从菜单中选择项目时,托管bean中的值不会直接更新,因为表单未提交。
通过<h:commandButton ...>
提交,或在菜单中使用ajax事件<f:ajax event="change" ...>
。
答案 1 :(得分:1)
除非我遗漏了什么,否则我认为你没有实例化你的转换器。你绑定到bean来获得转换器,但值是什么?
我可以理解你并不喜欢转换器中的数据库访问。如果你使用OmniFaces中的一个选择项转换器,几乎不需要这样做。
答案 2 :(得分:1)
关于您的代码的几点说明:
在托管bean ==错误设计的构造函数中执行操作,改为使用@PostConstructor
。
在转换器中手动实例化DAO ==糟糕的设计。理想情况下,您的DAO应该是可以注入转换器的托管对象(最好是EJB)。作为一个托管对象意味着它(理论上)可能是一个单例并由容器正确管理。至少这样,你不会感到难过。
尝试手动管理转换器。将转换器声明为独立组件,让容器完成它的工作,以避免不必要的调试。
variantsMenu
没有附加ajax处理程序,因此在提交整个表单之前,您不会在辅助bean中更新值
<h:selectOneMenu id="variantsMenu"
value="#{missionHandler.selectedVariant}"
converter="#{variantConverter}"
rendered="#{not empty missionHandler.selectedAircraftType}">
<f:ajax listener="#{missionHandler.changeVariant}" render="@form" />
<f:selectItem itemLabel="-- Select a Variant --" />
<f:selectItems value="#{missionHandler.variants}" var="variant"
itemValue="#{variant}" itemLabel="#{variant.commercialName}" />
</h:selectOneMenu>