2012-04-26 49 views
2

所以這不是一個很普遍的問題,但我希望有些人可以給我一些關於體系結構的指導,以便我可以構建下列可重用的檢票組件。構建可重複使用的檢票組件

這裏是skitch草圖:

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

我知道,偉大的圖畫吧?所以本質上,這個表單組件(我認爲這是正確的類)將被用來在表單上添加用戶定義的輸入數量。當用戶點擊TextInputField旁邊的 - 按鈕時,它將刪除該inputField。當他們按下+按鈕時,會添加一個新的空白字段。很顯然,當用戶單擊按鈕時,組件需要使用AJAX來更新組件,但我的問題是如何構造這個組件。這是一堂課嗎?兩個(一個用於整個組件,一個用於使用 - 按鈕的inputfield),我應該使用什麼類來執行此操作?我希望該對象儘可能通用以促進重用。以下是我迄今爲止:

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 

      } 

     }); 
    } 


} 

正如我所說的,我只是想習慣於考慮做出Wicket組件。我在面向對象方面有很多經驗,但並不特別關注門票。感謝您的幫助和指導!

回答

1

我猜最簡單的方法來實現所需的行爲將是使用列表支持的ListView。只需按下添加/刪除按鈕即可重新加載。

下面是一個代碼塗鴉(未測試)

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:

<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> 

我這個做的唯一特殊的是把一種形式圍繞ListView,因此我們只需在我們創建的Panel內提交(在此階段最有可能不需要驗證,並且應該以保存屏幕的形式進行驗證)。

這個實現的缺點是你總會重新加載完整的表單,因此會產生大量的開銷。只有1行被添加/刪除,但n( -/+)1被重新渲染。

+0

這實際上應該是一個更大形式的輸入組件。這就是爲什麼我認爲我應該使用formcomponent作爲超類。對不起,如果我不清楚我的問題,但讓我看看listview文檔。感謝您的迴應! – thatidiotguy 2012-04-26 21:11:00

+0

嗯,我只是不明白爲什麼你會想要通過創建一個新的FormComponent的麻煩,如果你可以輕鬆實現與ListView相同的行爲。但你可以看看FormComponentPanel(http://wicket.apache.org/apidocs/1.5/org/apache/wicket/markup/html/form/FormComponentPanel.html) – 2012-04-26 21:20:39

+0

啊我明白你的意思了。你的意思是我所尋找的行爲與列表視圖非常相似,甚至不值得它自己的對象。我會在早晨第一時間嘗試編碼。感謝您的努力和建議! – thatidiotguy 2012-04-26 21:50:02