【发布时间】: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(); }但它没有帮助... -
嗯,我觉得重写这个方法是不正确的……对不起