tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Harish Krishnaswamy <hkrishnasw...@comcast.net>
Subject Component recursion - some thoughts
Date Sun, 02 Nov 2003 20:05:23 GMT
Problem statement:
A component in Tapestry as we all know go through a one-time load phase 
before it can be rendered. At this phase the complete structure of the 
component is built. This poses a problem to recursive components as the 
complete structure will be unknown at this phase because the structure 
of these components are dependent upon the values of their bindings. So, 
bindings will have to be evaluated at this phase to load the complete 

Components in Tapestry, we also know, are pooled. So a recursive 
component loaded once may not be a complete component for a later 
rendition as the values of the bindings that determine the structure may 
change. This leaves us with the option to load the component dynamically 
during render as needed.

[I say the above to clarify my understanding of the problem, if this is 
wrong, the following may be irrelevant]

Solution Option 1:
During the load phase, create a synthetic component that contains all 
the necessary information to load the actual recursive component and 
drop it in place of the recursive component in the container. During 
render, when the synthetic component is encountered, load the recursive 
component (involves creating a new synthetic component for the next 
iteration in case it is needed) and render it, which involves updating 
the bindings. This newly created recursive component will replace the 
synthetic component in the container. Now when the exit condition is 
met, the recursion stops and unwinds to the topmost component. If the 
same page is used again with a different exit condition, it would still 
work because our inner most component is still a synthetic component 
that is capable of loading the actual recursive component and rendering it.

It is hard to explain it in words so let me try with an example.

Let's say we have a page, PageA. Let's say PageA has a component, CompA. 
Let's say component CompA has component, CompA (recursively), wrapped in 
a Conditional, ExitCompA, that determines the exit of the recursion 
(exit condition).

Now, when PageA is loaded, encounters CompA. Let's call this CompA_1 to 
denote the first encounter, CompA_i to denote the 'i'th encounter. So 
PageA instantiates CompA_1 and follows the following steps to construct 

   1. Loads all contained components in CompA_i including the
      Conditional ExitCompA,
   2. Encounters itself (CompA_i+1)
   3. Creates a synthetic component ("Recur" may be, that contains the
      info required to load CompA),
   4. Places the synthetic component "Recur" in place of CompA_i+1 in
   5. Loads all remaining contained components in CompA_i and completes
      loading CompA_i

PageA loads all remaining components in the page completes loading.

Now, when PageA is rendered, encounters CompA-1 and follows the 
following steps.

   1. Renders all contained components as usual (will update bindings)
   2. Encounters ExitCompA, evaluates the condition (based on updated
      bindings), if true go to step 3, if false go to step 6
   3. Encounters the synthetic component "Recur", instantiates CompA-i
      and follows the loading steps 1-5
   4. Replace the synthetic component "Recur" with the newly constructed
      component CompA_i
   5. Go to step 1
   6. Renders all remaining contained components in CompA-i

PageA renders all remaining components in the page and complets rendition.

Solution Option 2:

Hope this makes sense. Comments please.


  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message