Я пытаюсь найти разумный способ иметь дело с Forms in Wicket (я использую 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;
}
}
и, следовательно, он наследует все поля и поведение, определенные в суперклассах.
Это немного неудобно, если мне нужно переопределить валидатор добавляется к базовой PersonEditForm от EmployeeEditForm, но до сих пор, что не было требованием для меня ...
Однако это решение все еще требует от меня, чтобы дублировать разметку в подклассы, как показано ниже:
<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>
Это немного «Мех», особенно с учетом того, что некоторые лица имеют путь больше полей.
Я слышал, что некоторые люди используют композицию с FormComponentPanels, что, безусловно, было бы полезно для рендеринга некоторых объектов, которые можно использовать повторно, таких как объекты адреса и т. Д., Но я не уверен, как это будет работать в модели наследования.
Любые комментарии и/или советы от более опытных мастеров калитки, чем я был бы рад!
Большое спасибо заранее,
Энтони
Или FormComponentPanel? Я изучал это, и я начинаю думать, что это может быть лучшим подходом ... –
См. Javadoc FormComponentPanel, я думаю, что его значение отличается. Насколько я понимаю, это полезно для создания компонентов пользовательских форм, которые состоят из нескольких компонентов внутри, но предоставляют один вход после преобразования. – Bravehorsie
Уверен, но разве это не соответствует этому сценарию? Несколько внутренних полей обрабатывают свойства объекта и преобразуются в один вход, т. Е. сам объект (https://cwiki.apache.org/confluence/display/WICKET/Creating+Custom+FormComponentPanel's+to+build+valid+objects+using+Wicket's+Form+Validation+Logic). –