You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Hao Chen <ch...@hotmail.com> on 2005/04/21 22:14:34 UTC

Actions and Request Processing Lifecycle

Hi, all

I am confused by the request process sequence of Tapestry. It seems that 
action listeners are invoked when the components are rendered.  Why?  JSF 
has clear request processing lifecyle.  Is there any good doc on Tapestry?

I have a list page. In the page class, I load the list data in the 
pageBeginRender event. On the page, I have an ActionLink on each item to 
delete the item.  The problem is that:  Tapestry fires beginRender event --> 
my list data loads --> Tapestry renders each item --> AactionLink event 
triggered --> item is deleted from DB --> full page rendered.  But since the 
full list data is already loaded first, the deleted item is still shown on 
the page.

So, my questions are:
  -- What is the best time to load list data?
  -- Why are action listeners invoked during rendering instead of before 
rendering?
  -- How does tapestry identify which component to invoke action on? By some 
id? What happens if the list changes when the action is invoked (like some 
item was deleted by another person)?

Thanks,
- Hao



---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Actions and Request Processing Lifecycle

Posted by Nathan Kopp <nk...@mailshell.com>.
> The above process is the rewind process. It looks like normal
> rendering but actual no html code is output. Only after this
> rewind process, the real render process will begin. Then your
> pageBeingRender() method will be called again, so loading the
> list there will work.

As far as I understand it, pageBeginRender() is called twice - once when
replaying* (a.k.a. rewinding) the old page, and once when rendering the new
page.  These sometimes are the same page.  If that happens, then I'm pretty
sure that pageBeginRender is called twice on the same page.  You can
determine the difference between the two events by checking
event.getRequestCycle().isRewinding() from within the pageBeginRender()
method.

*Note: When Howard spoke at the Orlando Java User's Group meeting, he agreed
that the "rewind" cycle would be better called something else.  He suggested
possibly "replay", since it is basically replaying the page so that it can
accept the user's changes.

> >   -- Why are action listeners invoked during rendering instead of
> > before rendering?
>
> So that the components are restored to the same state
> as before (if nothing else has changed).

Also, page data changes during the render.  This is especially important if
you use an actionLink or a submit button inside a loop, since the listener
method will be called part-way through the execution of the loop, when
various loop variables are set to the current iteration.

This can sometimes cause problems, because the listeners are called in the
order that the components are rendered on the page.  Because of this, you
sometimes want to put the listener, for example, on the form instead of on a
submit button.

> > What happens if the list changes when the action is invoked
> > (like some item was deleted by another person)?
>
> Then you will get a StaleLinkException. That's why you should
> use a ListEdit component instead of a Foreach.

Another alternative is to store the list in the "visit" (similar to the
HttpSession) or in a persistent page property.  This way the page will be
"replayed" (re-rendered for rewind) in the same way that it was originally
generated, so that all of the components match.  With any of these
approaches (including ListEdit), of course, you'll need to write your own
rules to determine how to handle this situation, since it represents a
conflict in your data.

-Nathan



---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Actions and Request Processing Lifecycle

Posted by Kent Tong <ke...@cpttm.org.mo>.
Hao Chen <chenhao_70 <at> hotmail.com> writes:

> I am confused by the request process sequence of Tapestry. It 
> seems that action listeners are invoked when the components are 
> rendered.  Why?  JSF has clear request processing lifecyle.  
> Is there any good doc on Tapestry?

Try the user guide or 
http://www2.cpttm.org.mo/cyberlab/softdev/tapestry/index.html

> I have a list page. In the page class, I load the list data in the 
> pageBeginRender event. On the page, I have an ActionLink on each 
> item to delete the item.  The problem is that:  Tapestry fires 
> beginRender event --> my list data loads --> Tapestry renders each 
> item --> AactionLink event triggered --> item is deleted from DB --> 
> full page rendered.  But since the full list data is already loaded 
> first, the deleted item is still shown on the page.

The above process is the rewind process. It looks like normal
rendering but actual no html code is output. Only after this
rewind process, the real render process will begin. Then your
pageBeingRender() method will be called again, so loading the
list there will work.

However, ActionLink is pretty much useless. You should consider
using DirectLink instead.

> So, my questions are:
>   -- What is the best time to load list data?

In pageBeginRender().

>   -- Why are action listeners invoked during rendering instead of 
> before rendering?

So that the components are restored to the same state
as before (if nothing else has changed).

>   -- How does tapestry identify which component to invoke action 
> on? By some id? 

Yes.

> What happens if the list changes when the action is invoked 
> (like some item was deleted by another person)?

Then you will get a StaleLinkException. That's why you should
use a ListEdit component instead of a Foreach.


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org