我正试图找出一种合理的方式来处理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开发人员的评论和/或建议都比我最受欢迎!
非常感谢,
安东尼
答案 0 :(得分:1)
如果要在继承中重复使用标记,则应检查<wicket:child /> / <wicket:extends>
。
如果您想拥有一组可重复使用的表单字段,可以将它们放在面板而不是父表单中,然后将这个面板插入您希望的所有表单中。