Tapestry的rewind一直是學習和使用Tapestry的難點,rewind是用來處理表單提交的,表單默認使用的是
DirectService來提交。在詳細介紹之前,先說明下此文中需要用到的一些概念,首先是表單組件,我這里指的是指繼承自
AbstractFormComponent類的組件,例如:TextField、TextArea、Checkbox等,而不是具體的Form組件,表
單組件使用時必須在Form組件中,這些組件在rewind時調用繼承自AbstractFormComponent的
rewindFormComponent來讀取數據,并將數據賦值給容器或者頁面。
我們來看一下最簡單的TextField組件,組件定義如下
代碼
- <input??jwcid= "price@TextField" ?type= "text" ?value= "ognl:picture.price" ??translator= "translator:number,pattern=##.##" ??validators= "validators:min=0" ?displayName= "價格" ? class = "input_text" />??
再看一下TextField中的rewindFormComponent組件方法
代碼
- protected?void?rewindFormComponent(IMarkupWriter?writer,?IRequestCycle?cycle)?{??
- ???????//從請求中得到參數值??
- ????????String?value?=?cycle.getParameter(getName());??
- ??
- ????????try?{??
- ?????????????//用translator來轉換值??
- ????????????Object?object?=?getTranslatedFieldSupport().parse(this,?value);??
- //用validators來驗證值??
- ????????????getValidatableFieldSupport().validate(this,?writer,?cycle,?object);??
- ????????????//賦值給容器或者頁面??
- ????????????setValue(object);??
- ????????}?catch?(ValidatorException?e)?{??
- ????????????getForm().getDelegate().record(e);??
- ????????}??
- ????}??
可以看到在rewindFormComponent中,主要是從請求中取得用戶輸入的值,然后進行處理,最后賦值給容器或者頁面,上面的例子中會 調用頁面類的getPicture().setPrice(“用戶輸入的值”)來進行賦值。這樣整個表單的提交就可以理解為所有的表單組件讀取用戶輸入的 值并賦值給頁面的過程。
整個表單提交的詳細處理過程如下:
- * initialize():頁面初始化
* pageBeginRender() ("rewind"):getRequestCycle().isRewinding()為true
* rewind of the form / setting of properties:所有表單組件調用rewindFormComponent來取值賦值
* Deferred listeners (for Submit components):調用Submit組件的listener
* Form's listener:調用Form組件的listener
* pageEndRender() ("rewind"): getRequestCycle().isRewinding()為true
* pageBeginRender() (normal): getRequestCycle().isRewinding()為false
* pageEndRender() (normal): getRequestCycle().isRewinding()為false
代碼
- public?abstract?void?setPictures(List<Picture>?pictures);??
- public?abstract?void?setPictureInList();//用于For中的value??
- public?abstract?void?setPicture(Picture?picture);//用于表單創建??
- public?abstract?Picture?getPicture();??
- public?void?pageBeginRender(PageEvent?event)?{??
- if(getPicture()==null){??
- setPicture(new?Picture());??
- }??
- setPictures(getPictureService().findAll());??
- }??
代碼
- public?void?pageBeginRender(PageEvent?event)?{??
- if(getPicture()==null){??
- setPicture(new?Picture());??
- }??
- if?(!event.getRequestCycle().isRewinding())?{??
- setPictures(getPictureService().findAll());??
- }??
- }??