2012-04-26 4 views
2

매우 일반적인 질문은 아니지만 다음과 같은 재사용 가능한 개찰구 구성 요소를 만들 수 있도록 일부 사람들이 아키텍처에 대한 조언을 나에게 줄 수 있기를 바랍니다.재사용 가능한 개찰구 구성하기

https://skitch.com/cmagnollay/8sn2s/multitextform

내가 아는 큰 그림 오른쪽 :

다음은 Skitch에 대한 밑그림은? 그래서 본질적으로,이 formcomponent (나는 이것이 올바른 클래스라고 생각한다)는 폼에 사용자가 정의한 수의 입력을 추가하는 데 사용될 것이다. 사용자가 TextInputField 옆에있는 - 단추를 누르면 해당 inputField가 제거됩니다. + 버튼을 누르면 새로운 공백 필드가 추가됩니다. 분명히 사용자가 버튼을 클릭 할 때 구성 요소를 업데이트하려면 AJAX를 사용해야하지만 문제는이를 구성하는 방법입니다. 이게 하나의 수업인가요? 두 개 (전체 구성 요소 하나, - 버튼이있는 입력 필드 용),이 작업을 수행하기 위해 어떤 클래스를 사용해야합니까? 나는 재사용을 촉진하기 위해 가능한 한 일반적인 것을 목표로하고 싶다.

public class MultiTextInput<T> extends FormComponent<List<T>> 
{ 
    private static final long serialVersionUID = 1L; 

    private final String removeInputButtonName = "removeInputButton"; 
    private final String addInputButtonIdName = "addInputButton"; 

    private int numInputs = 1; 
    private List<TextField<T>> inputFieldList = new ArrayList<TextField<T>>(); 

    public MultiTextInput(String id, IModel<T> model) 
    { 
     super(id); 

     inputFieldList.add(new TextField<T>("input1", model)); 

     add(inputFieldList.get(0)); 
     addAddInputFieldMarkup(); 
    } 

    /** 
    * Adds an "add" button. 
    */ 
    private void addAddInputFieldMarkup() 
    { 
     Button addInputButton = new Button(this.addInputButtonIdName + numInputs); 
     addInputButton.add(new AjaxFormComponentUpdatingBehavior("onclick"){ 

      private static final long serialVersionUID = 1L; 

      @Override 
      protected void onUpdate(AjaxRequestTarget target) 
      { 
       numInputs++; 

       inputFieldList.add(new TextField<T>("input" + numInputs)); 

       target.add(MultiTextInput.this); 
      } 

     }); 
    } 

    /** 
    * Adds a "remove" button. 
    */ 
    private void addRemoveInputFieldMarkup() 
    { 
     Button removeInputButton = new Button(this.removeInputButtonName + numInputs); 
     removeInputButton.add(new AjaxFormComponentUpdatingBehavior("onclick"){ 

      private static final long serialVersionUID = 1L; 

      @Override 
      protected void onUpdate(AjaxRequestTarget arg0) 
      { 
       // TODO Auto-generated method stub 

      } 

     }); 
    } 


} 

내가 말했듯이, 난 그냥 개찰구 구성 요소를 만드는 방법에 대한 생각에 익숙해하려고 : 여기에 지금까지 가지고있는 것입니다. 저는 OO에 대한 많은 경험을 가지고 있지만, 개찰구와는별로 관련이 없습니다. 어떤 도움과 지침을 주셔서 감사합니다!

답변

1

원하는 동작을 구현하는 가장 쉬운 방법은 목록에서 지원하는 ListView를 사용하는 것입니다. 추가/제거 버튼을 누른 후 다시로드하십시오.

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.sourceforge.net/" xml:lang="en" lang="en"> 
<wicket:panel> 
    <form wicket:id="multiTextForm"> 
     <wicket:container wicket:id="listView"> 
      <input type="text" wicket:id="textField" /> 
      <a wicket:id="removeButton">-</a> 
     </wicket:container> 
    </form> 
    <a wicket:id="addButton">+</a> 
</wicket:panel> 

나는이 함께했던 유일한 특별한 일이 주위에 양식을 배치하는 것입니다 : 여기

은 (하지 테스트) 코드 낙서

public abstract class MultiTextPanel<T> extends Panel { 

public MultiTextPanel(String id, IModel<ArrayList<T>> model) { 
    super(id, model); 

    final Form<ArrayList<T>> multiTextForm = new Form<ArrayList<T>>("multiTextForm", model); 
    add(multiTextForm); 

    final ListView<T> listView = new ListView<T>("listView", model) { 

     @Override 
     protected void populateItem(final ListItem<T> item) { 
      // TODO Auto-generated method stub 
      TextField<T> textField = new TextField<T>("textField", item.getModel()); 
      add(textField); 

      AjaxSubmitLink removeButton = new AjaxSubmitLink("removeButton", multiTextForm) { 

       @Override 
       protected void onSubmit(AjaxRequestTarget target, Form<?> form) { 
        multiTextForm.getModelObject().remove(item.getModelObject()); 
        target.addComponent(multiTextForm); 
       } 

       @Override 
       protected void onError(AjaxRequestTarget target, Form<?> form) { 
        //errors should be ignored, we shoudlnt validate in our form, so this shouldnt happen anyway 
        multiTextForm.getModelObject().remove(item.getModelObject()); 
        target.addComponent(multiTextForm); 
       } 

      };    
      add(removeButton); 

     } 

    }; 
    add(listView); 

    AjaxSubmitLink addButton = new AjaxSubmitLink("addButton", multiTextForm) { 

     @Override 
     protected void onError(AjaxRequestTarget target, Form<?> form) { 
      //errors should be ignored, we shoudlnt validate in our form, so this shouldnt happen anyway 
      multiTextForm.getModelObject().add(createNewT()); 
      target.addComponent(multiTextForm); 
     } 

     @Override 
     protected void onSubmit(AjaxRequestTarget target, Form form) { 
      multiTextForm.getModelObject().add(createNewT()); 
      target.addComponent(multiTextForm); 
     } 
    }; 
    add(addButton); 



} 

public abstract T createNewT();} 

기본 HTML입니다 ListView를 사용하여 작성한 패널 내부에 제출할 수 있습니다 (유효성 검사는이 단계에서는 필요하지 않으며 화면을 저장하는 형식으로 수행해야합니다).

이 구현의 단점은 전체 양식을 항상 다시로드하므로 많은 오버 헤드가 발생한다는 것입니다. 1 행만 추가/제거되지만 n (-/+) 1은 다시 렌더링됩니다.

+0

실제로 이것은 더 큰 형식의 입력 구성 요소 일뿐입니다. 이것이 내가 formcomponent를 수퍼 클래스로 사용해야한다고 생각한 이유입니다. 미안, 내 질문에 명확하지 않은 경우,하지만 listview 문서를 체크 아웃하자. 응답 주셔서 감사합니다! – thatidiotguy

+0

글쎄, 왜 내가 ListView로 같은 동작을 쉽게 할 수 있다면, 새로운 FormComponent를 만드는 번거 로움을 겪고 싶어하는지 모르겠다. 하지만 FormComponentPanel (http://wicket.apache.org/apidocs/1.5/org/apache/wicket/markup/html/form/FormComponentPanel.html) –

+0

을 확인할 수 있습니다. 아 무슨 뜻인지 알 겠어. 당신은 내가 바라는 행동이리스트 뷰와 매우 유사하다는 것을 의미합니다. 저는 아침에 코드를 먼저 시험해 보겠습니다. 노력과 조언에 감사드립니다! – thatidiotguy