2014-11-10 3 views
0

Я пытаюсь найти разумный способ иметь дело с 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, что, безусловно, было бы полезно для рендеринга некоторых объектов, которые можно использовать повторно, таких как объекты адреса и т. Д., Но я не уверен, как это будет работать в модели наследования.

Любые комментарии и/или советы от более опытных мастеров калитки, чем я был бы рад!

Большое спасибо заранее,

Энтони

ответ

1

Вы должны проверить <wicket:child />/<wicket:extends>, если вы хотите использовать разметку в наследстве.

Если вы хотите иметь многоразовый набор полей формы, вы можете поместить их в панель вместо родительской формы и вставить эту панель во все формы, которые вы хотите.

+0

Или FormComponentPanel? Я изучал это, и я начинаю думать, что это может быть лучшим подходом ... –

+1

См. Javadoc FormComponentPanel, я думаю, что его значение отличается. Насколько я понимаю, это полезно для создания компонентов пользовательских форм, которые состоят из нескольких компонентов внутри, но предоставляют один вход после преобразования. – Bravehorsie

+0

Уверен, но разве это не соответствует этому сценарию? Несколько внутренних полей обрабатывают свойства объекта и преобразуются в один вход, т. Е. сам объект (https://cwiki.apache.org/confluence/display/WICKET/Creating+Custom+FormComponentPanel's+to+build+valid+objects+using+Wicket's+Form+Validation+Logic). –

Смежные вопросы