【问题标题】:Wicket - form components losing reference when PropertyModel is updatedWicket - 更新 PropertyModel 时表单组件丢失参考
【发布时间】:2018-01-26 05:34:06
【问题描述】:

我有一个包含一些字段和 DropdownChoices 的表单。其中一个是动态填充的:当 State 被填充时,City 下拉菜单会更新,直到这里都可以。

动态填充的下拉菜单(我使用 hibernate 作为 ORM):

// in my form constructor
// umf is my model
umf = new Umf();

DropDownChoice stateChoice = new DropDownChoice<State>(
    "states",
    new PropertyModel(umf, "state"),
    em.createQuery("from State e").getResultList(),
    new ChoiceRenderer<State>("name")
);

DropDownChoice citiesChoice = new DropDownChoice<City>(
    "cities",
    new PropertyModel(umf, "city"),
    new ArrayList<City>(),
    new ChoiceRenderer<>("name")
);

当我尝试清除表单和我的模型以让表单为其他提交做好准备时,问题出现在第一次表单提交之后(发生正常)。

第一个问题是在 onSubmit 方法中,在将对象持久化到数据库后,我为我的模型设置了一个新对象:umf = new Umf();,以便准备好持久化一个新的 umf。在此之后,组件似乎丢失了 umf 引用。

定义下拉状态模型的行:new PropertyModel(umf, "state") 不再起作用,因为即使我更改下拉列表中的状态,umf.state PropertyModel 也未更新(始终为 0),因此未填充城市下拉列表。

// right after statesChoice and citiesChoice declaration

statesChoice.add(new AjaxFormComponentUpdatingBehavior("change") {
    @Override
    protected void onUpdate(AjaxRequestTarget target) {
        citiesChoice.setChoices(
            em.createQuery("from City m where m.state.id = :state_id")
            .setParameter("state_id", umf.getState().getId())
            .getResultList()
        );
        target.add(cititesChoice);
    }
});

Wicket 是这样工作的吗?如果组件的属性模型引用接收到一个新对象,组件会丢失它的引用并需要显式重置?

【问题讨论】:

    标签: java forms hibernate wicket dropdownchoice


    【解决方案1】:

    new PropertyModel(umf, "state") 更改为new PropertyModel(form.getModel(), "umf.state")city 也一样。

    您面临的问题是,一旦您将umf 传递给PropertyModel,它就会作为自己的成员字段保存在其中。稍后您更改了 Form 中的引用,但 PropertyModel 仍然指向其成员字段,即旧的。

    通过传递表单的模型,它变得动态 - 每次 PropertyModel 需要状态时,它都会向表单的模型询问其模型对象。

    【讨论】:

    • 感谢您的澄清,通过您的回答,我找到了解决方案,但是由于您在 Wicket 团队中,我有一些问题:- onSubmit 方法我正在运行clearInput(),但它不起作用,只有当表单验证失败时..为什么? - 使用 CompoundPropertyModel 总是好的? - 使用它,有必要保留简单的组件引用(如 TextFields),或者我可以简单地添加它们 add(new TextField("name", model.bind("name"),跳过 TextField 声明?在此先感谢:)
    【解决方案2】:

    找到了解决办法。我开始使用 CompoundPropertyModel 的形式:

    umf = new Umf();
    CompoundPropertyModel model = new CompoundPropertyModel(umf);
    setDefaultModel(model);
    

    然后组件模型引用它:

    nameModel = new RequiredTextField("name", model.bind("name"));
    
    DropDownChoice statesChoice = new DropDownChoice<State>(
        "states",
        new PropertyModel(getModel(), "state"),
        em.createQuery("from Estado e").getResultList(),
        new ChoiceRenderer<State>("name")
    );
    // and so on
    

    提交后(onSubmit方法):

    umf = new Umf();
    

    这样组件就不会丢失表单的引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-19
      相关资源
      最近更新 更多