Java ApacheWicket:验证错误后如何更新模型
我有dateTimeField和ListView的表单。 ListView看起来是这样的:Java ApacheWicket:验证错误后如何更新模型,java,apache,validation,wicket,Java,Apache,Validation,Wicket,我有dateTimeField和ListView的表单。 ListView看起来是这样的: final ListView<String> countryView = new ListView<String>("country", model.<List<String>>bind("country")) { @Override protected void populateItem(final List
final ListView<String> countryView = new ListView<String>("country", model.<List<String>>bind("country")) {
@Override
protected void populateItem(final ListItem<String> item) {
final String country = item.getModelObject();
item.add(new ValidationDisplayableLabel("country", country, new String[] { modelPath }));
item.add(new AjaxLink("deleteLink") {
@Override
public void onClick(AjaxRequestTarget target) {
model.getObject().getCountry().remove(country);
if (issPeriod) {
addButton.setVisible(true);
countryTextField.setVisible(true);
findButton.setVisible(true);
}
if (target != null)
target.addComponent(rowPanel);
}
});
}
};
countryTextField = new ValidationDisplayableTextField("countryCodeInput", model.bind("oneCountry"), "job.country.value");
**countryView.setReuseItems(true);**
rowPanel.add(countryView);
rowPanel.add(countryTextField);
addButton.setOutputMarkupPlaceholderTag(true);
rowPanel.add(addButton);
AjaxSubmitLink addButton = new AjaxSubmitLink(LinkNames.addCountry.toString()) {
@Override
public void onSubmit(AjaxRequestTarget target, Form form) {
if (model.getObject().getOneCountry() != null)
addCountry();
if (target != null)
target.addComponent(rowPanel);
target.addComponent(form.getPage().get("feedbackPanel"));
}
@Override
protected void onError(AjaxRequestTarget target, Form<?> form)
{
onSubmit(target, form);
}
};
final ListView countryView=新列表视图(“国家”,model.bind(“国家”)){
@凌驾
受保护的无效填充项(最终列表项){
最后一个字符串country=item.getModelObject();
add(新的ValidationDisplayableLabel(“country”,country,新字符串[]{modelPath}));
添加(新的AjaxLink(“删除链接”){
@凌驾
公共void onClick(AjaxRequestTarget目标){
model.getObject().getCountry().remove(国家);
如有(第二期){
addButton.setVisible(true);
countryTextField.setVisible(true);
设置可见(true);
}
如果(目标!=null)
target.addComponent(行面板);
}
});
}
};
countryTextField=new ValidationDisplayableTextField(“countryCodeInput”、model.bind(“oneCountry”)、“job.country.value”);
**countryView.setReuseItems(true)**
rowPanel.add(countryView);
rowPanel.add(countryTextField);
addButton.setOutputMarkupPlaceholderTag(真);
rowPanel.add(添加按钮);
addButton看起来像这样:
final ListView<String> countryView = new ListView<String>("country", model.<List<String>>bind("country")) {
@Override
protected void populateItem(final ListItem<String> item) {
final String country = item.getModelObject();
item.add(new ValidationDisplayableLabel("country", country, new String[] { modelPath }));
item.add(new AjaxLink("deleteLink") {
@Override
public void onClick(AjaxRequestTarget target) {
model.getObject().getCountry().remove(country);
if (issPeriod) {
addButton.setVisible(true);
countryTextField.setVisible(true);
findButton.setVisible(true);
}
if (target != null)
target.addComponent(rowPanel);
}
});
}
};
countryTextField = new ValidationDisplayableTextField("countryCodeInput", model.bind("oneCountry"), "job.country.value");
**countryView.setReuseItems(true);**
rowPanel.add(countryView);
rowPanel.add(countryTextField);
addButton.setOutputMarkupPlaceholderTag(true);
rowPanel.add(addButton);
AjaxSubmitLink addButton = new AjaxSubmitLink(LinkNames.addCountry.toString()) {
@Override
public void onSubmit(AjaxRequestTarget target, Form form) {
if (model.getObject().getOneCountry() != null)
addCountry();
if (target != null)
target.addComponent(rowPanel);
target.addComponent(form.getPage().get("feedbackPanel"));
}
@Override
protected void onError(AjaxRequestTarget target, Form<?> form)
{
onSubmit(target, form);
}
};
AjaxSubmitLink addButton=新的AjaxSubmitLink(LinkNames.addCountry.toString()){
@凌驾
提交时公共无效(AjaxRequestTarget目标,表单){
如果(model.getObject().getOneCountry()!=null)
addCountry();
如果(目标!=null)
target.addComponent(行面板);
target.addComponent(form.getPage().get(“feedbackPanel”);
}
@凌驾
受保护的void onError(AjaxRequestTarget目标,表单)
{
onSubmit(目标、形式);
}
};
问题是,当我的DateTime字段失败时(例如,将小时数设置为100),在countryTextField中输入国家代码,然后按add按钮,它会在反馈面板中显示验证消息,小时范围不正确,但不添加国家。这是因为我的模型没有更新。也许有办法手动更新它?所以会显示验证消息,但国家/地区列表视图仍然可以更新
整个表单的提交在另一个按钮上,所以从逻辑上讲,添加国家是正常的,即使dateTimeField中存在验证错误
谢谢
另外,我已经读了很多关于类似问题的帖子,但大多数都是用.setReuseItems(true)解决的,但在我的案例中它不起作用
p.p.S ApacheWicket 1.4.17在我的项目中,我遇到了一个类似的问题,我发现的解决方法是使用一个特殊的访问者。即使提交的输入无效,它也会更新模型
public class VisitorUpdateModelWithoutValidation implements FormComponent.IVisitor {
public Object formComponent(IFormVisitorParticipant formComponent) {
if (formComponent instanceof FormComponent) {
final FormComponent<?> formComponent1 = (FormComponent<?>) formComponent;
boolean required = formComponent1.isRequired();
if (required) {
formComponent1.setRequired(false);
}
formComponent1.modelChanging();
formComponent1.validate();
formComponent1.updateModel();
formComponent1.modelChanged();
if (required) {
formComponent1.setRequired(true);
}
}
return Component.IVisitor.CONTINUE_TRAVERSAL;
}
}
公共类VisitorUpdateModelWithout验证实现FormComponent.IVisitor{
公共对象formComponent(IFormVisitorParticipant formComponent){
if(formComponent的formComponent实例){
最终FormComponent FormComponent 1=(FormComponent)FormComponent;
布尔值required=formComponent1.isRequired();
如果(需要){
formComponent1.setRequired(false);
}
formComponent1.modelChanging();
formComponent1.validate();
formComponent1.updateModel();
formComponent1.modelChanged();
如果(需要){
formComponent1.setRequired(true);
}
}
返回Component.IVisitor.CONTINUE\u遍历;
}
}
只需在行为的
onSubmit
方法中使用它:getForm().visitFormComponents(新的VisitorUpdateModelWithoutValidation())代码>作为此答案的更新,在Wicket 6中,您可以通过覆盖以下形式的onError()来完成此操作:
@Override
protected void onError() {
super.onError();
this.updateFormComponentModels();
}
您可以在目标更新之前对正在更新的字段发出field.clearInput()
。对我来说,这感觉非常糟糕,不是您的代码,而是wicket不会更新模型,除非表单经过验证。我不明白您的观点。验证器的目的是确保模型对象不包含无效数据。更新它们没有多大意义。模型更新限制仅在表单提交(通常)时才重要。此wicket行为不仅在提交时限制模型更新,而且在任何其他事件中也会限制模型更新。例如,我的复选框“其他组件的模型更新”事件在验证错误后将永远不会在屏幕上显示当前状态。对我来说,这是一些“邪恶”的小门行为。这是非常有帮助的。谢谢!