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());
- }
- }