论坛首页 入门技术论坛

Tapestry4中是否控件定义与放置位置有关?

浏览 7561 次
该帖已经被评为新手帖
作者 正文
   发表时间:2006-10-14  
环境:T4
Home.html

<html><body jwcid="@Body">
     <table width="246" border="0" cellpadding="0" cellspacing="0" align="center">
       <form jwcid="submitForm">
          <tr><td width="219" height="16" valign="top">
              input1<input type="text" name="textfield" jwcid="input1"/>
          </td></tr>
          <tr><td height="23" valign="top">
              <input type="submit" name="Submit2" jwcid="submit1"/>
          </td></tr>
          <tr><td height="21" valign="top">
              <input type="submit" name="Submit22" jwcid="submit2"/>
          </td></tr>
          <tr><td height="29" colspan="2" valign="top">
              input2<input type="text" name="textfield22" jwcid="input2"/>
          </td></tr>
      </form>
    </table>
</body></html>

Home.page

<component id="submitForm" type="Form"/>
<component id="input1" type="TextField">
          <binding name="value" value="input1"/>
</component>
<component id="input2" type="TextField">
          <binding name="value" value="input2"/>
</component>
<component id="submit1" type="Submit">
          <binding name="listener" value="listener:submit1"/>
</component>
<component id="submit2" type="Submit">
          <binding name="listener" value="listener:submit2"/>
</component>

Home.java


public abstract class Home extends BasePage{

          @InjectPage("Home")
          public abstract Home getHome();
          private String input1;
          private String input2;
          public String getInput1() {
                    return input1;
          }
          public void setInput1(String input1) {
                    this.input1 = input1;
          }
          public String getInput2() {
                    return input2;
          }
          public void setInput2(String input2) {
                    this.input2 = input2;
          }
          public IPage submit1(){
                    this.setInput2(this.getInput1()+this.getInput2());
                    return getHome();
          }
          public IPage submit2(){
                    this.setInput1(this.getInput1()+this.getInput2());
                    return getHome();
          }
         }

运行程序,对input1,input2,submit1,submit2操作如下:
1,在input1中输入1;input2中输入2,如图:

2,点击submit1,得到如下结果:

3,重复步骤1, 在input1中输入1;input2中输入2,然后点击submit2,得到如下结果:

------------------------------------------------------------------
上述,操作中input2根本没有接受任何参数,但是input1却是正常的,请问这个问题是什么原因造成?是否是bug.
   发表时间:2006-10-14  
Tapestry把一切都看成是组件,自然TextField组件和Submit组件也就没有任何区别,他们都会被一视同仁,谁先定义谁就先被执行。

你把input2放在submit2之后,那么input2将会在submit2执行完之后才能获取从表单传入来的值

你在input2和submit2中放一些mark就知道了

    public void setInput2(String input2) {
        this.input2 = input2;
        System.out.println("我是setInput2(),我运行拉");
    }

    public IPage submit2(){
        setInput1(getInput1() + getInput2());
        System.out.println("我是submit2(),我运行拉");
        return this;
    }

如果按照
input1<input jwcid="input1"/><br>
<input type="submit" value="Submit1" jwcid="submit1"/><br>
<input type="submit" value="Submit2" jwcid="submit2"/><br>
input2<input jwcid="input2"/><br>

这样定义,那么我们可以得到的输出是:

我是submit2(),我运行拉
我是setInput2(),我运行拉

很明显,赋值发生在调用之后。所以会有null出现

不知道我解释得对不对哈~~
0 请登录后投票
   发表时间:2006-10-14  
to vlinux:
很明显,赋值发生在调用之后。所以会有null出现


submit仅仅是listener,页面的控件无论放在何处,只要处于form里面,在接受调用的时候都应该产生作用。
在我给的例子中,两个text是故意分开来放置的,如果按照你的说法,那么submit永远必须在页面的低端?
现在问题的关键是,调用submit时,input2没有正常的工作。这到底html页面设置问题,还是程序的问题?

BTW:我另外测过,将input1,input2调置submit控件之前(html中),一切ok.
0 请登录后投票
   发表时间:2006-10-15  
我认为你的错误是因为代码的原因造成的。

“submit仅仅是listener,页面的控件无论放在何处,只要处于form里面,在接受调用的时候都应该产生作用。”
这句是没有错,但是仅仅用在
<form jwcid="@Form" listener="listener:emptySubmit">

这里

你定义的是Submit组件,但是并没有告诉Tapestry你的Form的listener是谁。

所以我们可以这样写代码

Home.html
<html>
    <body>

        <form jwcid="@Form" listener="listener:emptySubmit">
            input1<input jwcid="@TextField" value="ognl:input1"/><br>
            <input type="submit" jwcid="@Submit" value="submit1" action="listener:submit1"/><br>
            <input type="submit" jwcid="@Submit" value="submit2" action="listener:submit2"/><br>
            input2<input jwcid="@TextField" value="ognl:input2"/><br>
        </form>

    </body>
</html>



Home.java
public abstract class Home extends BasePage{
    
    public abstract String getInput1();
    public abstract String getInput2();
    public abstract void setInput1( String input1 );
    public abstract void setInput2( String input2 );
    
    public abstract String getInput3();
    
    public void submit1(){
        setInput1( getInput1() + getInput2() );
    }
    
    public void submit2(){
        setInput2( getInput2() + getInput1() );
    }
    
    public IPage emptySubmit(){
        return this;
    }
}



这样就可以了。

综上所述,我个人认为你的错误是代码造成的,欢迎拍砖~呵呵
0 请登录后投票
   发表时间:2006-10-15  
public abstract String getInput3();

是测试时候用的,忘记删掉了,不好意思

顺便说一下,为什么这里的代码那么丑陋,就不能把
 
弄得好看点么
0 请登录后投票
   发表时间:2006-10-17  
to vlinux:

thank you!
代码我测了,一切ok!
但还是有一个问题,难道一点不能在submit1或submit2中实现调用吗?
请教原理。^_^
0 请登录后投票
   发表时间:2006-10-17  
yi527 写道
to vlinux:

thank you!
代码我测了,一切ok!
但还是有一个问题,难道一点不能在submit1或submit2中实现调用吗?
请教原理。^_^


原理vlinux讲过了
vlinux 写道

Tapestry把一切都看成是组件,自然TextField组件和Submit组件也就没有任何区别,他们都会被一视同仁,谁先定义谁就先被执行。



更具体一点,是(详细请参见文档和源代码):
submit被点击之后,执行form.rewind,page开始进入rewind流程(cycle.isRewound=true):
1、form中各个实现了IFormComponent的组件根据其在模版中定义的先后次序开始执行各自的rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle)方法。

对于submit这样的带有监听事件的form组件,rewindFormComponent(writer, cycle)会调用其listener方法;

对于textfield这样的接受输入值的form组件,rewindFormComponent(writer, cycle)会将recycle中的request parameter值bind到textfield的value表达式。

2、最后执行form的listener事件方法。

因此对于你的这个测试来说,submit在模版中位于input之前,而要在submit的监听事件中得到input的值,是不可以的。

vlinux给出一个解决办法是把submit的事件处理放在form的listener中,目前来讲好像没有更好的办法。
0 请登录后投票
   发表时间:2006-10-18  
谢谢vlinux和sorphi。
0 请登录后投票
   发表时间:2006-10-18  
受教了...最近刚好在学TAPESTRY...没有注意到这个问题..呵呵..
0 请登录后投票
   发表时间:2006-10-18  
使用submit的action属性代替lisener
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics