访问Wicket表单验证器中的任意数量的字段

Jon*_*nik 3 java validation wicket

我需要验证几个类型的Wicket输入字段TextField<BigDecimal>(即百分比之和为100).有一到多个这样的输入字段; 事情是,我事先并不知道有多少.

(简化示例)

private class PercentageValidator extends AbstractFormValidator {
    @Override
    public FormComponent<?>[] getDependentFormComponents() {
        // ...
    }

    @Override
    public void validate(Form<?> form) {
        List<TextField<BigDecimal>> fields = // TODO

        // the actual validation where the value of every field is needed
    }
}
Run Code Online (Sandbox Code Playgroud)

ListView的Java代码:

ListView<?> listView = new ListView<PropertyShare>("shares", shares) {
    @Override
    protected void populateItem(ListItem<PropertyShare> item) {
    // ... 
        item.add(new TextField<BigDecimal>("share", ... model ...));
    }
};
Run Code Online (Sandbox Code Playgroud)

HTML:

<tr wicket:id="shares">
   <td> ... </td>
   <td>
     <input wicket:id="share" type="text" size="4"> %
   </td>

</tr>
Run Code Online (Sandbox Code Playgroud)

我尝试将每个TextField保存在Page上的集合中,但是这种方法失败,因为populateItem()封闭的方法ListView不仅被调用,而且首先创建了Page,因此重复的字段被添加到集合中.(我无法想出一个简单的方法来保持它没有重复.)

使用ListView这一事实似乎也有点复杂,从方法中的表单对象中查找字段validate().我想我需要获取ListView form.get("shares")并遍历其子项?

访问转发器所包含的任意数量字段的"正确方法"是ListView什么?

biz*_*lop 5

另一种方法是子类化TextField,然后使用a Visitor来挑选子类的所有后代组件.

通过这种方式,您可以避免未经检查的转换,并且您不必依赖于ID,这不是一种非常强大的方法.

编辑:在实践中,它看起来像这样:

子类:

private static class ShareField extends TextField<BigDecimal> {
   // ...
}
Run Code Online (Sandbox Code Playgroud)

从表单中查找所有ShareField的Helper方法:

private List<ShareField> findShareFields(Form form) {
    final List<ShareField> fields = Lists.newArrayList();
    form.visitChildren(ShareField.class, new IVisitor<ShareField>() {
        @Override
        public Object component(ShareField component) {
            fields.add(component);
            return CONTINUE_TRAVERSAL;
        }
    });
    return fields;
}
Run Code Online (Sandbox Code Playgroud)