Wicket Form在验证失败后加载空值

时间:2016-02-26 10:36:06

标签: java wicket wicket-6

我们在wicket 6项目中遇到了麻烦。我们有一个通过AJAX加载的表单。

当我们的表单验证失败时,我们无法正确地将其他对象加载到模型中(失败的字段为空)。

我试图创建新对象(我的modelobject值= new MyObject())并且验证失败:

enter image description here

然后,如果我从左侧的树中选择已经创建的对象,我可以看到空字段:

enter image description here

但实际上这个对象已经设置了所有字段:

enter image description here

表单标记:

<wicket:panel>
        <div wicket:id="feedback"></div>
        <form wicket:id="form" role="form" class="form-horizontal">
            <div class="form-group">
                <label wicket:for="shortName" class="control-label col-sm-4"><wicket:message key="shortName"></wicket:message></label>
                <div class="col-sm-8">
                    <input type="text" class="form-control" wicket:id="shortName" />
                </div>
            </div>
            <div class="form-group">
                <label wicket:for="fullName" class="control-label col-sm-4"><wicket:message key="fullName"></wicket:message></label>
                <div class="col-sm-8">
                    <input type="text" class="form-control" wicket:id="fullName" />
                </div>
            </div>
            <div class="form-group">
                <label wicket:for="parentServiceGroup" class="control-label col-sm-4"><wicket:message key="parentServiceGroup"></wicket:message></label>
                <div class="col-sm-8">
                    <select type="text" class="form-control width-abs" wicket:id="parentServiceGroup"></select>
                </div>
            </div>
            <div class="form-group">
                <label wicket:for="status" class="control-label col-sm-4"><wicket:message key="status"></wicket:message></label>
                <div class="col-sm-8">
                    <select class="form-control width-abs" wicket:id="status"></select>
                </div>
            </div>
            <div>
                <a wicket:id="save" class="btn btn-primary"></a>
                <a wicket:id="cancel" class="btn btn-default"></a>
            </div>
        </form>
    </wicket:panel>

表格代码:

@Override
protected void onInitialize() {
    super.onInitialize();
    add(new MiraFeedbackPanel("feedback"));
    final Form form = new Form("form", CompoundPropertyModel.of(getDefaultModel())) {
        @Override
        protected void onError() {
            super.onError(); 
            this.updateFormComponentModels();
        }

    };
    add(form);
    form.add(new TextField("shortName").setRequired(true));
    form.add(new TextField("fullName"));
    form.add(new DropDownChoice("status", Arrays.asList(CommonStatus.values()), 
            new ChoiceRenderer<CommonStatus>("name")).setRequired(true));
    form.add(new ServiceGroupDropDownChoice("parentServiceGroup", getServiceGroupModelObject()));
    form.add(new AjaxSubmitLabeledLink("save", "Save", form) {
        @Override
        protected void onError(AjaxRequestTarget target, Form<?> form) {
            super.onError();
            error(getString("savingError"));
            target.add(ServiceGroupEditPanel.this.get("feedback"));
        }

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
            getServiceGroupModelObject().setDateCreated(new Date());
            getServiceGroupModelObject().setWorkerCreated(UserSession.get().getWorker());
            getServiceGroupModelObject().setDateModification(new Date());
            getServiceGroupModelObject().setWorkerModification(UserSession.get().getWorker());
            DAOService.ejbCommonBean().saveEntity(getServiceGroupModelObject());
            info(getString("serviceGroupSaved"));
            target.add(ServiceGroupEditPanel.this.get("feedback"));
            target.add(ServiceGroupEditPanel.this.getParent().getParent()
                    .get("serviceGroupsTree"));
        }
    });
    form.add(new AjaxLabeledLink("cancel", "Cancel") {
        @Override
        public void onClick(AjaxRequestTarget target) {
            getServiceGroupModel().setObject(null);
            target.add(ServiceGroupEditPanel.this.getParent().getParent()
                    .get("serviceGroupsTree"));
            target.add(ServiceGroupEditPanel.this.getParent().getParent()
                    .get("serviceNotSet"));
            target.add(ServiceGroupEditPanel.this.getParent().getParent()
                    .get("selectedServiceGroup"));
            target.add(ServiceGroupEditPanel.this.getParent());
        }
    });
}

我们尝试了此问题的解决方法:Apache wicket: how to update model after validation error但它没有帮助。

UPD:我试图更新模型的树的代码:

add(new DefaultNestedTree<ServiceGroup>("serviceGroupsTree", new ServiceGroupsTreeProvider()) {

        @Override
        protected Component newContentComponent(String id, IModel<ServiceGroup> node) {
            return new Folder<ServiceGroup>(id, this, node) {
                @Override
                protected Component newLabelComponent(String id, IModel<ServiceGroup> model) {
                    return new Label(id, PropertyModel.of(model, "shortName"));
                }

                @Override
                protected MarkupContainer newLinkComponent(String id, final IModel<ServiceGroup> model) {
                    return new AjaxLink(id, model) {
                        @Override
                        public void onClick(AjaxRequestTarget target) {
                            serviceGroupModel.setObject(DAOService.ejbCommonBean()
                                    .getEntityFullFetch(
                                            ServiceGroup.class, 
                                            model.getObject().getUidservicegroup()
                                    ));
                            target.add(ServiceGroupListPage.this.get("selectedServiceGroup"));
                            target.add(ServiceGroupListPage.this.get("serviceNotSet"));
                            target.add(ServiceGroupListPage.this.get("tabs"));
                            ((ServiceGroupEditPanel)editPanelTab.getPanel("editTab")).onModelObjectChanged(target);
                        }
                    };
                }
            };
        }
    }

我们的表单已添加到AjaxTabbedPanel:

final ServiceGroupEditPanelTab editPanelTab = new ServiceGroupEditPanelTab("editTab", serviceGroupModel);
    List<ITab> tabsList = new ArrayList<>();
    tabsList.add(editPanelTab);
    tabsList.add(new ServiceGroupServicesPanelTab("servicesTab", serviceGroupModel));

    final AjaxTabbedPanel tabs = new AjaxBootstrapTabbedPanel("tabs", tabsList);
    tabs.setSelectedTab(0);
    add(tabs);

UPD2: 我已添加sample project to Github来显示我的问题。在README.md中,有重现错误的步骤。

1 个答案:

答案 0 :(得分:4)

如果您只是在模型中交换对象,那么所有表单组件仍将保留以前的原始输入。

在您更改了模型对象后,即在您从树中选择了不同的实体后,调用表单#clearInput()。