[ 
https://issues.apache.org/jira/browse/MYFACES-3570?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13295534#comment-13295534
 ] 

Leonardo Uribe commented on MYFACES-3570:
-----------------------------------------

Thanks for the example. Unfortunately the example proposed is not going to 
work, because ignores some concepts about PSS and facelets algorithm.

A detailed explanation about why c:forEach is considered broken from design can 
be found at MYFACES-3389.

This case looks different from MYFACES-3389, because all id generation strategy 
was changed in MYFACES-3329 with a more stable and fast algorithm. In this 
case, the block that is not removed has the same internal facelets id as the 
one is added, so it is just skipped in 
FaceletCompositionContextImpl.finalizeForDeletion().

I know all that explanation is too technical. In few words Partial State Saving 
(PSS) algorithm introduced a restriction over facelets algorithm: when a view 
is created by first time by vdl.buildView, it should be possible to restore the 
same view executing vdl.buildView and applying a "delta" state. c:forEach 
changes the component tree each time it is executed, breaking PSS concept at 
all.

So, aparently the hack "works" in Mojarra, but it is broken from inside, 
because later you'll see other problems with PSS algorithm for all components 
inside c:forEach block (state get lost for some components and other problems). 

The rule to use c:forEach is if the underlying model does not change over 
application lifetime, you can use it, otherwise there are better options as 
described on:

http://lu4242.blogspot.com/2011/06/jsf-component-state-per-row-for.html

But maybe is not what you want. I could suggest make blocksList static and 
application, and instead add a property to B called isEnabled(). Instead change 
the model, you can play with the property and then inside the page do this:

      <c:forEach items="#{progBean.blocksList}" var="blc">
        <c:if test="#{blc.enabled}">
        <f:subview>
        <h:panelGroup styleClass="containser">
          <ui:include src="#{blc.blockName}.xhtml" />
        </h:panelGroup>
        <br/>
        </f:subview>
        </c:if>
      </c:forEach>

In that way, the internal ids generated by facelets algorithm will be stable 
(the same and unique per option in blocksList). The c:if works as condition for 
include the block, and f:subview is a NamingContainer component, which ensure 
clientIds generated in the inside will be unique. I know it is too elaborate, 
but is the only thing that will work in such dynamic way and will be reliable, 
at least in MyFaces.

I'll close this issue as invalid.

                
> c:forEach may cause MyFaces to be buggy (works fine on mojarra)
> ---------------------------------------------------------------
>
>                 Key: MYFACES-3570
>                 URL: https://issues.apache.org/jira/browse/MYFACES-3570
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: General
>    Affects Versions: 2.1.7
>         Environment: Tomcat JRE 6
>            Reporter: Faissal Boutaounte
>         Attachments: MyFaces.zip
>
>
> We are building a dynamic form and to do we're using 4 blocks of code ( pages 
> :b1.xthml,b2.xhtml, b3.xhtml and b4.xhtml ) that are included using a 
> c:forEach loop and ui:include.
> Clicking on a link make the application iterate over a list and includes 
> blocks dynamically.
> imagine section 1 has 1 block and section 2 has tow blocks. when user click 
> section1's link and the section's 2 link it's fine, but when he click 
> section's 1 link he got tow blocks instead of one. it sames like the last 
> block  from section 2 is still here although sectino 1 has only one block

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to