Jsf 2 h:SelectOne菜单值在重新显示页面后不会从模型中读取
我偶然发现了一个奇怪的问题,我一整天都在试图解决它。我没能在下面这个简单的例子中重现它,但也许有人能给我一些想法 查看代码:Jsf 2 h:SelectOne菜单值在重新显示页面后不会从模型中读取,jsf-2,cdi,Jsf 2,Cdi,我偶然发现了一个奇怪的问题,我一整天都在试图解决它。我没能在下面这个简单的例子中重现它,但也许有人能给我一些想法 查看代码: <h:selectOneMenu id="color" value="#{testModel.color}" required="true" converter="#{colorConverter}"> <f:selectItems id="colorList" value="#{testModel.colorList}"
<h:selectOneMenu id="color"
value="#{testModel.color}" required="true"
converter="#{colorConverter}">
<f:selectItems id="colorList"
value="#{testModel.colorList}"
var="colorVar" itemLabel="#{colorVar.name}" itemValue="#{colorVar}"/>
</h:selectOneMenu>
这个小例子很好用。但在现实生活中,Color
对象是从域对象映射而来的DTO
。我尝试只初始化颜色列表一次,并在转换器中使用其项,以便ColorConverter#getAsObject
从颜色列表返回一个项
所以,问题是这个。在
更新模型
阶段,所选项目被正确转换并设置为模型。然后在Invoke Application
阶段调用TestModel#save
方法,该方法返回null,这意味着应重新显示相同的页面。但在重新加载页面后,列表将再次初始化,所选项目将重置。我希望它会显示保存在模型中的选定项。您是否100%确定DTO的equals()
方法是正确的?我也在考虑它,但我决定使用固定值列表,而不是实现正确的equals。正如我所说的,转换器从列表中直接选择对象,该对象用作f:selectItems的值。我知道这很容易出错,我可能应该尝试实现equals。我会检查这个,然后把结果发回来。谢谢你的提示!我只是不知道如何解释“列表再次初始化,所选项目重置”部分。你真的调试过这个吗,或者对最终用户来说,它只是“看起来”一样吗?我调试过了。在Render Responce
阶段,会为列表的每个项目调用转换器,这可能还可以,但我不确定。所选的项被重置
我的意思是最终用户看起来是这样的,而不是模型值被更新。@BalusC-Nah,equals工作正常。。。事实上,当重新提交表单时,我在更新模型阶段看到,模型中的旧项值是正确的。所以,问题是,在重置值时,最终用户只会觉得它“像”,而实际上它不是。
@javax.inject.Named
@javax.enterprise.context.SessionScoped
public class TestModel implements Serializable {
private Color color;
//color getters and setters
private static final List<Color> colorList;
static {
// in real example I initialize this list from database
colorList = new ArrayList<Color>();
colorList.add(Color.getRedColor());
colorList.add(Color.getGreenColor());
colorList.add(Color.getBlueColor());
}
public List<Color> getColorList() {
return colorList;
}
public String save() {
//doing some stuff
// stay on the same page
return null;
}
}
@Named
@ApplicationScoped
public class ColorConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
return value != null ? Color.valueOf(value) : null;
}
@Override
public String getAsString(FacesContext context, UIComponent component,
Object value) {
if (value instanceof Color) {
return ((Color) value).getName();
}
return null;
}
}