我对问题Dynamic <optgroup> support in wicket的回答包括一个使用WebMarkupContainer和SelectOptions组件进行样式设置的“选择”框。
我实际上是在扩展Form的类中使用它,并在超类构造函数中使用具有“ select”属性(以及其他属性)的bean作为CompoundPropertyModel。 MyBean类型的Bean可以属于以Group2Bean表示的一个内部组,而每个Bean可以依次属于由Group1Bean表示的一个外部组。
代码(修改为隐藏机密性和数据库检索)大致如下:
Select的HTML代码:
<select wicket:id="select">
<wicket:container wicket:id="outerRV">
<optgroup wicket:id="optGroup1">
<wicket:container wicket:id="rv">
<optgroup wicket:id="optGroup2">
<wicket:container wicket:id="selectOptions">
<option wicket:id="option"></option>
</wicket:container>
</optgroup>
</wicket:container>
</optgroup>
</wicket:container>
</select>
整个表单的Java代码:
public class MyForm extends Form<FilterBean> {
public MyForm(String id, FilterBean filterBean) {
super(id, new CompoundPropertyModel<FilterBean>(filterBean);
/*
* ...code to get group1Beans and group2Beans...
*/
/* Select */
Select select = new Select("select");
select.setRequired(true);
add(select);
/* markup repeater for each group1 division */
RepeatingView rvOuter = new RepeatingView("outerRV");
select.add(rvOuter);
for(Group1Bean group1Bean : group1Beans){ /* for each group1 division */
/* container with unique wicket ID */
WebMarkupContainer overOptgroup1 = new WebMarkupContainer(rv.newChildId());
rv.add(overOptgroup1);
/* outer optgroup, name taken from group1Bean */
WebMarkupContainer optGroup1 = new WebMarkupContainer("optGroup1");
overOptGroup.add(optGroup1);
optGroup1.add(
new AttributeModifier("label",true,
new Model<String>(group1Bean.getName()
))
);
/* markup repeater for each group2 division */
RepeatingView rv = new RepeatingView("rv");
select.add(rv);
for(Group2Bean group2bean : group2Beans){ /* for each group2 division */
/* container with unique wicket ID */
WebMarkupContainer overOptgroup2 =
new WebMarkupContainer(rv.newChildId());
rv.add(overOptgroup2);
/* inner optgroup, name taken from group2Bean and indented */
WebMarkupContainer optGroup2 = new WebMarkupContainer("optGroup2");
overOptGroup.add(optGroup2);
optGroup2.add(new AttributeModifier("style",true,
new Model<String>("padding-left:15px")));
optGroup2.add(new AttributeModifier("label",true,
new Model<String>(group2Bean.getName())));
/* fetches and displays MyBean options for selected group2 division */
optGroup2.add(
new SelectOptions<MyBean>(
"selectOptions",fetchMyBeansUnder(group2Bean)
new MyBeanRenderer()
).add(new AttributeModifier("style",true,
new Model<String>("padding-left="30px")))
);
}
}
问题是,模型的select属性不会更新。即使我在生成的Webapp界面上更改了选择,按下一个(默认)提交按钮也会给我一个“需要选择”的反馈,并且尝试将其链接到其他失败的组件将无法为select属性检索值。
尝试从1.4.6升级到具有通用Select的1.5.6,但问题并未解决。选择的扩展和摆弄使我将问题缩小到所选的SelectOption,当Select的inputConverter()(按下提交按钮后调用)在选项上调用getDefaultModelObject()时返回null。
大家有什么想法吗?提前谢谢了。
最佳答案
好的,我发现了,这是一个愚蠢的错误。使用SelectOption的构造函数,不会为每个选项自动创建模型,而是由MyBeanRenderer的getModel()方法创建;我返回了一个空模型,而不是从bean参数创建的模型。我什至没有想到它可能是渲染器……这只是将一种方法更改为以下内容的问题:
public IModel<T> getModel(T bean){
return new Model<T>(bean);
}
仍然不敢相信我花了数周时间却没有看到这个。
关于java - Wicket SelectOption <T>在Select <T>进行的getDefaultModelObject()调用上返回null,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10513833/