On 11/3/05, Mike Kienenberger <[EMAIL PROTECTED]> wrote:
Not actually true, or it couldn't have passed the TCK :-).
That is superceded, for UIData, by the javadocs on that class itself.
Going back to the original question, the reason for UIData to deal with grandchildren directly is explicity described in the javadocs quoted earlier -- it allows UIData to perform the iteration over the underlying data model. Among other things, that means UIData actually calls things like processDecodes() *multiple* times on the same grandchildren ... once per row. UIColumn doesn't get involved in this at all, other than being a container for the contents of the grandchildren that will be rendered inside that column zero or more times (indeed, it doesn't even have a renderer).
If you want a different design for managing iteration, you'll need to design your own iteration component hierarchy.
Craig
In fact, according to
http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/UIComponentBase.html#processDecodes(javax.faces.context.FacesContext)
I'd say MyFaces is not following the JSF 1.1 api for UIData.
Not actually true, or it couldn't have passed the TCK :-).
The
javadocs state "Call the processDecodes() method of all facets and
children of this UIComponent, in the order determined by a call to
getFacetsAndChildren()." and that's not currently happening since
there are no calls to UIColumn.processDecodes().
That is superceded, for UIData, by the javadocs on that class itself.
Going back to the original question, the reason for UIData to deal with grandchildren directly is explicity described in the javadocs quoted earlier -- it allows UIData to perform the iteration over the underlying data model. Among other things, that means UIData actually calls things like processDecodes() *multiple* times on the same grandchildren ... once per row. UIColumn doesn't get involved in this at all, other than being a container for the contents of the grandchildren that will be rendered inside that column zero or more times (indeed, it doesn't even have a renderer).
If you want a different design for managing iteration, you'll need to design your own iteration component hierarchy.
Craig
At minimum, you should open a JIRA issue on this.
-Mike
On 11/3/05, Mike Kienenberger < [EMAIL PROTECTED]> wrote:
> To me, your suggested changes make a lot of sense. I don't see
> anything in the spec that says it has to be done the way it's
> currently being done.
>
> The only things I see are:
>
> 4.1.3 UIData
>
> ==================================================
> Only children of type
> UIColumn should be processed by renderers associated with this component.
> ==================================================
>
>
> ====================
> UIData specializes the behavior of the processDecodes(),
> processValidators(), and processUpdates() methods inherited from its
> parent as follows:
> For each of these methods, the UIData implementation must iterate over each
> row in the underlying data model, starting with the row identified by the first
> property, for the number of rows indicated by the rows property, by calling the
> setRowIndex() method.
> When iteration is complete, set the rowIndex property of this
> component, and of
> the underlying DataModel, to zero, and remove any request attribute exposed
> via the var property.
> ====================
>
>
> =============================================
> 4.1.1 UIColumn
> UIColumn (extends UIComponentBase) is a component that represents a single
> column of data with a parent UIData component. The child components of a
> UIColumn will be processed once for each row in the data managed by the parent
> UIData.
> =============================================
>
> On 11/3/05, Simon Kitching < [EMAIL PROTECTED]> wrote:
> > Hi,
> >
> > For an HTML table, much of the decoding process is in fact controlled by
> > the components rather than the renderer.
> >
> > In the class javax.faces.component.UIData, method
> > "processColumnChildren" (which is called by processDecodes) does this:
> >
> > for (Iterator it = getChildren().iterator(); it.hasNext();)
> > {
> > UIComponent child = (UIComponent) it.next();
> > if (child instanceof UIColumn)
> > {
> > if (!child.isRendered())
> > {
> > //Column is not visible
> > continue;
> > }
> > for (Iterator columnChildIter = child.getChildren()
> > .iterator(); columnChildIter.hasNext();)
> > {
> > UIComponent columnChild = (UIComponent) columnChildIter
> > .next();
> > process(context, columnChild, processAction);
> > }
> > }
> > }
> >
> > And that last call to process them calls component.processDecodes, which
> > delegates to the renderer as needed.
> >
> > However this code means UIData is accessing its *grandchildren*
> > directly, rather than just its children. I don't believe this is very
> > nice OO design; UIData's children should be responsible for managing
> > their own children, ie the UIColumn class should be told to process the
> > children rather than calling getChildren on it and manipulating those
> > directly.
> >
> > And in my case, I'm trying to write a custom UIColumn class, but am not
> > able to get control of the decode process because the decoding calls go
> > directly to the children of my custom component rather than to the
> > custom component itself.
> >
> > Have I misunderstood anything here? If not, would there be interest in
> > patching this so UIData delegates to UIColumn rather than accessing the
> > grandchildren directly? Or perhaps this is not possible due to the JSF spec?
> >
> >
> > Thanks,
> >
> > Simon
> >
>

