Apache Wicket:如何在验证错误后更新模型

3

我有一个包含dateTimeField和ListView的表单。ListView看起来像这样:

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);
        }
    };

事实是,当我在dateTimeField中失败(例如将小时设置为100),在countryTextField中输入国家代码并按addButton时,它会在反馈面板中显示验证消息,指出小时范围不正确,但不添加该国家。这是因为我的模型没有更新。也许有一种方法可以手动更新它?因此,即使仍然可以更新country listView,也会显示验证消息?
整个表单的提交是在另一个按钮上完成的,因此逻辑上即使在dateTimeField中存在验证错误,也可以添加国家。
谢谢!
附言:我已经阅读了很多关于类似问题的帖子,但大多数帖子都是通过.setReuseItems(true)解决的,但在我的情况下无法解决。
附言:Apache wicket 1.4.17
3个回答

6
作为对此答案的更新,在Wicket 6中,您可以通过在表单中重写onError()方法来实现此功能:
@Override
    protected void onError() {
    super.onError();
    this.updateFormComponentModels();
}

5

我在项目中遇到了类似的问题,我找到了一个解决方法,就是使用一个特殊的访问者。它会更新模型,即使提交输入无效。

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;
    }
}

只需在您的行为的 onSubmit 方法中使用它:

getForm().visitFormComponents(new VisitorUpdateModelWithoutValidation());。这将更新模型而无需进行验证。


1
对我来说,这感觉非常糟糕,不是你的代码的问题,而是因为Wicket除非表单经过验证,否则不会更新模型。 - Berlin Brown
我不明白你的观点。验证器的目的是确保模型对象不包含无效数据。更新它们没有太多意义。 - Sebastian vom Meer
模型更新限制只有在提交表单时才是重要的(通常情况下)。这个Wicket行为不仅限制了提交时的模型更新,还限制了任何其他事件中的模型更新。例如,我的复选框模型在其他组件事件上的更新,在验证错误后永远不会在屏幕上显示当前状态。对我来说,这是一种“邪恶”的Wicket行为。 - will824

3
您可以在更新字段之前,对需要更新的字段使用field.clearInput() 方法进行清除。

这非常有帮助。非常感谢! - ozeray

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接