Wicket Forms的继承问题

时间:2014-11-10 17:28:24

标签: inheritance layout wicket

我正试图找出一种合理的方式来处理Wicket中的Forms(我正在使用6.17),特别是关于继承和避免代码重复。

以下是我目前正在使用的典型架构:

public class PersonEditPanel<T extends Person> extends BasePanel<T> {

    public PersonEditPanel(String id, IModel<T> model) {    
        super(id, model);
        steOutputMarkupId(true);
    }

    @Override
    protected void onInitialize() {
        super.onInitialize();

        add(newPersonForm("form", getModel());
    }

    protected Form newPersonForm(String id, IModel<T> model) {

        return new PersonEditForm(id, model);
    }

    protected class PersonEditForm extends Form<T> {            

        protected PersonEditForm(String id, IModel<T> model) {
            super(id, CompoundPropertyModel.<T>of(model);
        }

        @Override
        protected void onInitialize() {
            super.onInitialize();

            TextField<String> name = new TextField<String>("name") {

                @Override
                public boolean isRequired() {
                    return isNameRequired();
                }
            }; 
            name.add(StringValidator.lengthBetween(2, 40));
            name.setLabel(new ResourceModel("label.name"));

            add(name);

            add(new SimpleFormComponentLabel("nameLabel", name));

            TextField<String> surname = new TextField<String>("surname") {

                @Override
                public boolean isRequired() {
                    return isSurnameRequired();
                }
            }; 
            surname.add(StringValidator.lengthBetween(2, 40));
            surname.setLabel(new ResourceModel("label.surname"));

            add(surname);

            add(new SimpleFormComponentLabel("surnameLabel", surname));

            // and so on ...
        }

        @Override
        protected void onSubmit() {
            PersonEditPanel.this.onSubmit();
        }

        @Override
        protected void onCancel() {
            PersonEditPanel.this.onCancel();
        }
    }

    protected boolean isNameRequired() {
        return true;
    }

    protected boolean isSurnameRequired() {
        return true;
    }

    protected void onSubmit() {}

    protected void onCancel() {}
}

这是标记:

<wicket:panel>
    <form wicket:id="form">
        <div>    
            <label wicket:id="nameLabel"></label>
            <input wicket:id="name" type="text"/>
        </div>
        <div>                
            <label wicket:id="surnameLabel"></label>
            <input wicket:id="surname" type="text"/>
        </div>
    </form>
</wicket:panel>

因此,当我需要编辑Person的子类,比如Employee时,我按如下方式扩展PersonEditPanel:

public class EmployeeEditPanel extends PersonEditPanel<Employee> {

    public EmployeeEditPanel(String id, IModel<Employee> model) {
        super(id, model);
    }

    @Override
    protected Form newPersonForm(String id, IModel<Employee> model) {

        return new PersonForm(id, model) {

            @Override
            protected void onInitialize() {
                super.onInitialize();

                TextField<String> role = new TextField<String>("role") {

                    @Override
                    public boolean isRequired() {
                        return isRoleRequired();
                    }
                }; 
                role.setLabel(new ResourceModel("label.role"));

                add(role);   

                add(new SimpleFormComponentLabel("roleLabel", role));
            }
        };
    }

    protected boolean isRoleRequired() {
        return true;
    }
}

因此它继承了超类中定义的所有字段和行为。

如果我需要覆盖从EmployeeEditForm添加到基础PersonEditForm的验证器,但到目前为止这对我来说并不是一个要求,这有点尴尬......

但是这个解决方案仍然要求我在子类中复制标记,如下所示:

<wicket:panel>
    <form wicket:id="form">
        <div class="field">    
            <label wicket:id="nameLabel"></label>
            <input wicket:id="name" type="text"/>
        </div>
        <div class="field">                
            <label wicket:id="surnameLabel"></label>
            <input wicket:id="surname" type="text"/>
        </div>
        <div class="field">
            <label wicket:id="roleLabel"></label>
            <input wicket:id="role" type="text"/>
        </div>
    </form>
</wicket:panel>

这有点'meh',特别是考虑到某些实体有更多的字段。

我听说有些人使用FormComponentPanels组合,这肯定有助于渲染一些可重复使用的实体,例如Address实体等。但我不确定这在继承模型中是如何工作的。

任何经验丰富的Wicket开发人员的评论和/或建议都比我最受欢迎!

非常感谢,

安东尼

1 个答案:

答案 0 :(得分:1)

如果要在继承中重复使用标记,则应检查<wicket:child /> / <wicket:extends>

如果您想拥有一组可重复使用的表单字段,可以将它们放在面板而不是父表单中,然后将这个面板插入您希望的所有表单中。