【问题标题】:Wicket Form loads empty values after validation fails验证失败后,Wicket Form 加载空值
【发布时间】:2016-02-26 10:36:05
【问题描述】:

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

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

我正在尝试创建新对象(我的模型对象值 = new MyObject())并且验证失败:

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

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

表单标记:

<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 中有重现错误的步骤。

【问题讨论】:

  • 您能解释一下应用程序的最终用户执行的工作流程吗?在屏幕截图中,不清楚用户输入的信息是什么,如何输入 - 通过 UI 或以编程方式。我觉得您需要在设置新模型对象之前调用 Form.clearInput(),以防您以编程方式完成所有这些操作。
  • 好吧,我在解释……
  • - 第一个屏幕截图 - 用户试图创建一个新实体。 - 他按下绿色按钮“创建新服务组”。我们表单的模型对象设置为 new MyObject()。表单重新渲染。 - 用户按下“保存”按钮,验证失败(截图 №1)。 - 然后,如果用户在验证失败后立即从树中选择其他对象,他将在表单中看不到任何内容(表单对象设置正确但字段为空但必须以编程方式更改)(屏幕截图№2)。让我试试 Form.clearInput()
  • 我试图以如下形式覆盖 onModelChanged() 方法:@Override protected void onModelChanged() { super.onModelChanged(); this.clearInput(); } 但它没有帮助...
  • 嗯,我觉得重写这个方法是不正确的……对不起

标签: java wicket wicket-6


【解决方案1】:

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

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

【讨论】:

  • 很抱歉,我卡了这么久,因为我无法尝试您的建议,因为我在编码时遇到了另一个异常...我用树的代码更新了我的问题从哪里我正在尝试清除表单的输入()。我认为 TabbedPanel 有问题,因为我的 Form 在里面,而 form = null 所以我得到了 NPE。我真的不知道如何解决它。
  • 我已将示例项目添加到我的 Github - github.com/sanluck/wicket-form-in-tabs-sample - 以显示我的问题。在 README.md 中有重现错误的步骤。我不知道 - 也许是 Wicket 错误??
  • 我创建了一个拉取请求。
猜你喜欢
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 2012-11-15
  • 1970-01-01
  • 2014-11-25
  • 1970-01-01
  • 2021-11-18
  • 1970-01-01
相关资源
最近更新 更多