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
