【发布时间】:2010-09-01 09:32:44
【问题描述】:
我们不断从用户那里得到的一个问题是选择(下拉列表或多选)具有依赖值。例如,用户会选择一个国家/地区,然后系统会使用该国家/地区的城市填充城市下拉列表。
我已经在会话(或会话范围)中经常进行这项工作,但现在,对于真正的轻量级场景,我希望让它在请求范围内工作。
这里有一些显示问题的虚拟代码(通常我们会使用 A4J 来填充下拉菜单而无需完全刷新,但也可以使用普通的 jsf 来演示该问题):
JSF:
<h:form>
<p>
<h:selectOneMenu value="#{bean.selectedSourceValue}">
<f:selectItems value="#{bean.sourceValues}" />
</h:selectOneMenu>
</p>
<p>
<h:selectOneMenu value="#{bean.selectedDependentValue}">
<f:selectItems value="#{bean.dependentValues}" />
</h:selectOneMenu>
</p>
<p>
<h:commandButton value="submit" />
</p>
</h:form>
支持 bean:
public class Bean {
private Integer selectedSourceValue;
private Integer selectedDependentValue;
/**
* @return values for the first selection. Numbers from 1 to 10.
*/
public List<SelectItem> getSourceValues(){
List<SelectItem> r = new ArrayList<SelectItem>();
for(int i=1; i<=10; i++){
r.add(new SelectItem(i));
}
return r;
}
/**
* @return values for the second selection. First ten powers of the selected first value.
*/
public List<SelectItem> getDependentValues(){
if (selectedSourceValue==null) return Collections.emptyList();
List<SelectItem> r = new ArrayList<SelectItem>();
for(int i=1; i<=10; i++){
r.add(new SelectItem((int)Math.pow(selectedSourceValue, i)));
}
return r;
}
// ... snipped some basic getter and setters
}
看起来很简单。问题是在进行第二次选择时。提交第二个下拉列表时,将验证组合。但在验证阶段,请求范围的 bean 尚未填充,因此 getDependentValues() 返回 null。这会导致 jsf 抛出 NoSuchElementException(使用 Sun RI)。
关于如何解决这个问题的任何想法,甚至是否可能?
【问题讨论】: