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

psi*_*yev 2 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 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);
Run Code Online (Sandbox Code Playgroud)

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);
        }
    };
Run Code Online (Sandbox Code Playgroud)

问题是,当我失败我DateTimeField字段(如组个小时到100),在countryTextField输入国家或地区代码,并按下Add按钮,它在反馈面板显示验证消息,这一个小时的范围是不正确的,但不要加国.这是因为我的模型没有更新.也许有办法手动更新它?因此将显示验证消息,但国家listView仍然可以更新?

整个表单的提交是在其他按钮上,所以从逻辑上讲,即使dateTimeField中存在验证错误,添加国家也是正常的.

谢谢!

PS我已经阅读了很多关于类似问题的帖子,但是大多数都是用.setReuseItems(true)解决的,但它在我的情况下不起作用.

PPS Apache wicket 1.4.17

Joh*_*nyK 6

作为此答案的更新,在Wicket 6中,您可以通过覆盖窗体中的onError()来实现此目的:

@Override
    protected void onError() {
    super.onError();
    this.updateFormComponentModels();
}
Run Code Online (Sandbox Code Playgroud)


Ced*_*tay 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

只需在onSubmit您的行为方法中使用它: getForm().visitFormComponents(new VisitorUpdateModelWithoutValidation());