Wicket Form 在验证失败后加载空值
Wicket Form loads empty values after validation fails
我们的 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
中有重现错误的步骤。
如果您只是交换模型中的对象,您的所有表单组件仍将保留之前的原始输入。
在更改模型对象后调用 Form#clearInput(),即在您从树中选择不同的实体后。
我们的 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
中有重现错误的步骤。
如果您只是交换模型中的对象,您的所有表单组件仍将保留之前的原始输入。
在更改模型对象后调用 Form#clearInput(),即在您从树中选择不同的实体后。