Wicket SelectOption <t>在select <t> </t> </t>的getDefaultModelObject()调用上返回null

时间:2012-05-09 09:58:49

标签: java html wicket

我对问题Dynamic <optgroup> support in wicket的回答包括一个使用WebMarkupContainer和SelectOptions组件进行样式设置的选择框。

我实际上试图在扩展Form的类中使用它,并使用带有“select”属性的bean(以及其他)作为超类构造函数中的CompoundPropertyModel。 MyBean类型的Bean可以属于由Group2Bean表示的一个内部组,并且每个Bean都可以属于由Group1Bean表示的一个外部组。

代码(修改为隐藏机密和数据库检索)或多或少如下:

选择的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属性的值。 / p>

尝试从1.4.6升级到1.5.6,它具有通用Select,但问题并没有得到解决。扩展和摆弄Select导致我将问题缩小到所选的SelectOption返回null 选择的inputConverter()(按下提交按钮后调用)调用选项上的getDefaultModelObject()

任何想法,伙计们?非常感谢提前。

1 个答案:

答案 0 :(得分:1)

好的,我发现了,这是一个愚蠢的错误。使用SelectOption的构造函数,不会为每个选项自动创建模型,而是由MyBeanRenderer的getModel()方法创建;我返回了一个空模型,而不是从bean参数创建的模型。我甚至认为它不是渲染器......只是将一种方法更改为以下内容:

public IModel<T> getModel(T bean){
    return new Model<T>(bean);
}

仍然无法相信我花了几周时间才看到这一点。