Hi, for spec I've created bug few days ago: http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1002
but I didn't realize how deep impact this bug have: I did a training about JSF implicit objects in our company and now practically every coder uses #{component.something} :) For myfaces: https://issues.apache.org/jira/browse/MYFACES-3157 Leonardo Uribe píše v St 25. 05. 2011 v 12:36 -0500: > Hi > > I have seen that. The problem is in spec javadoc, the behavior for > UIComponent.process* > and encode* is clear about the ordering. > > In theory, pushComponentToEL should be called before any call to > isRendered, but after > isTransient. Look on MyFaces UIComponentBase.processRestoreState. It has this > > public void processRestoreState(FacesContext context, Object state) > { > if (context == null) > { > throw new NullPointerException("context"); > } > > Object[] stateValues = (Object[]) state; > > try > { > // Call > UIComponent.pushComponentToEL(javax.faces.context.FacesContext, > javax.faces.component.UIComponent) > pushComponentToEL(context, this); > > // Call the restoreState() method of this component. > restoreState(context, stateValues[0]); > > The spec javadoc says the opposite, restoreState should be called "before" > pushComponentToEL but in practice that breaks > UIComponent.EventListenerWrapper. > I reported the bug long time ago, but it wasn't fixed (I don't know why). > > This case is similar. This should be fixed on the spec, but I don't > see a reason why we shouldn't commit that into myfaces code, because > after all, nobody relies on the buggy behavior. > > I think we should open a new issue on the spec issue tracker: > > http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC > > but fix it on myfaces code. > > regards, > > Leonardo Uribe > > 2011/5/25 Martin Koci <martin.kocicak.k...@gmail.com>: > > Hi, > > > > <h:form> > > <h:panelGroup> > > <h:inputText id="testId" > > rendered="#{component.id eq 'testId'}" > > value="#{bean.value}" /> > > </h:panelGroup> > > </h:form> > > > > please notice the expression: > > > > rendered="#{component.id eq 'testId'}" > > > > that is clearly true. > > > > But that does not work as expected: inputText is rendered, but never > > updates model value. > > > > > > Problem 1. > > > > from specification, methods UIComponent.process* and encode* > > 1) If the rendered property of this {@link UIComponent} > > false, skip further processing > > 2) Call {@link #pushComponentToEL} > > > > -> #{component} resolves in rendered="#{}" to parent! > > > > > > Problem 2. > > > > MyFaces implement that (pointless) requirement inconsistently: from > > UIComponentBase.process*: > > > > (!isRendered()) > > return; > > pushComponentToEL(context, this) > > > > and from UIComponentBase.encodeBegin* > > pushComponentToEL(context, this); > > if (isRendered()) > > > > > > causes that example above renderes inputText, but never updates model. > > > > Problem 3. > > > > RendererUtils.renderChild(FacesContext, UIComponent): > > in this method it is unappropriate to use following code: > > > > if (!child.isRendered()) { > > return; > > } > > child.encodeBegin(facesContext); > > > > because: > > 1) it does not take into account pushComponentToEL ( #{component} > > resolves to parent) > > 2) behaviour is incosistent with UIComponent.encodeBegin : you'll get > > "random" rendering - depends if parent of component renders it's > > children or not! For this case I've created MYFACES-3126, but I'll > > reopen it now, because simple remove of 'if (!child.isRendered())' does > > not solve that problem and causes another problem if component > > getRendersChildren = false; > > > > > > What do yout think about this problem? > > > > > > Regards, > > > > Kočičák > > > > > > >