Hi Mario, Simon,

indeed, this is a bug - I just looked at the Renderer source-code more
carefully. Funny thing is - I thought I had fixed this bug once, and
now, there it is again. Maybe I fixed it at some other place.

regards,

Martin

On 10/24/07, Simon Kitching <[EMAIL PROTECTED]> wrote:
> ---- "Sochor Zdeněk" <[EMAIL PROTECTED]> schrieb:
> > Hi,
> >   as to why does it work, the answer should be simple - almost all
> > renderers in MyFaces  do ALL encoding work  in encodeEnd method
> > (including rendering children).
>
> To be more specific (he says, after some hurried study of the code):
>
> Normally it is the role of the ViewHandler to call
> encodeBegin/encodeChildren/encodeEnd on all components. Because content in
> the template needs to be woven into output from JSF components, generating a
> view is not just walking the component tree.
>
> However components where rendersChildren=true are different. In that case
> the child components all need to be built before encodeBegin is called on
> the "rendersChildren" component. So  (at least for JSF1.1+jsp) the
> ViewHandler just limits itself to building the components, *not* invoking
> their encode methods. The rendersChildren component is then responsible for
> invoking the children.
>
> The Renderer implementation of encodeChildren below does indeed seem buggy
> to me; it correctly handles one level of children but fails if a component
> that sets rendersChildren=true has grandchildren.
>
> However in practice I think every component that implements encodeChildren
> always overrides this buggy default and invokes something like
> RenderUtils.renderChildren to do it properly. There aren't very many of
> them.
>
> As Sochor mentioned, many of them do this in the renderer encodeEnd,
> although some do it in encodeChildren.
>
> > But what do i wonder more is why page's component tree contains ALL
> > previously rendered/encoded components.
> > Wouldn't it make sense to remove non-rendered components from it?
> > I came across this issue when discussing topic: "TabbedPane does not
> > validate non-selected tabs in server side tab switching mode (Relaed to
> > TOMAHAWK-1012 <https://issues.apache.org/jira/browse/TOMAHAWK-1012>)."
> >
> > Best regards,
> >   Zdenek
>
>
> Non-rendered components can still have state configured into them by java
> code. Setters can be called on those components to set properties, and each
> component has an arbitrary Attributes map that can hold data. Discarding the
> non-rendered component would discard that data.
>
> I think another reason is that when re-rendering a page it is quite tricky
> to match up component declarations in the "template" file with existing
> components in the tree. When every component in the template file has an
> explicit id there is no trouble, but that is not usually the case. The only
> solution when a tag in the template file is found without an id is to assume
> it corresponds to the next anonymous component in the existing view tree.
> This "guessing" approach doesn't work well if components get removed from
> the tree just because they are not rendered. But the thought of absolutely
> requiring an id on every h:outputText and h:outputLabel in the template file
> is not tempting.
>
> I cannot think of any other reasons, but these seem enough to me.
>
>
> Regards,
>
> Simon
>
> --
> A. Because it breaks the logical sequence of discussion
> Q. Why is "top posting" bad?
>
>
>
> ============
>
>
> >
> > Mario Ivankovits napsal(a):
> > > Hi!
> > >
> > > In JSF 1.1 I am curious about the javax.faces.renderer.Renderer class in
> > > JSF 1.1, in particular the following piece of code:
> > >
> > >     public void encodeChildren(FacesContext context,
> > >                                UIComponent component)
> > >             throws IOException
> > >     {
> > >         if (context == null) throw new NullPointerException("context");
> > >         if (component == null) throw new
> NullPointerException("component");
> > >
> > >         List children = component.getChildren();
> > >         for (int i=0; i<children.size(); i++)
> > >         {
> > >             UIComponent child = (UIComponent) children.get(i);
> > >
> > >             if (!child.isRendered())
> > >             {
> > >                 continue;
> > >             }
> > >
> > >             child.encodeBegin(context);
> > >             if (child.getRendersChildren())
> > >             {
> > >                 child.encodeChildren(context);
> > >             }
> > >             child.encodeEnd(context);
> > >         }
> > >     }
> > >
> > >
> > > I wonder WHEN are the children rendered if the component returns false
> > > on getRendersChildren here.
> > > And how/why does it work when mixing things, lets say you have
> > > t:div/h:panelGroup/t:div
> > > where t:div returns false on getRendersChildren() and h:panelGroup
> > > returns true.
> > >
> > > Is there a simple answer to this?
> > >
> > > Ciao,
> > > Mario
>
>


-- 

http://www.irian.at

Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German

Professional Support for Apache MyFaces

Reply via email to