Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am new to JSF and I am struggling with dynamicaly rendering included pages. My code looks like this:

MenuBean

@ViewScoped
public class MenuBean implements Serializable {

    private MenuItem[] menuItems = new MenuItem[] {
        new MenuItem("page_1", "/page_1.xhtml"),
        new MenuItem("page_2", "/page_2.xhtml"),
    };

    private String selectedItemLabel;

    //...
}

MenuItem

public class MenuItem implements Serializable {

    private String label;
    private String page;

    //...
}

index.xhtml

    <ui:repeat var="menuItem" value="#{menuBean.menuItems}">                                    
        <h:panelGroup rendered="#{menuBean.selectedItemLabel eq menuItem.label}" layout="block">
            <h:outputText value="#{menuBean.selectedItemLabel}" />                              
            <ui:include src="#{menuItem.page}" />                                           
        </h:panelGroup>                                                                     
    </ui:repeat>                                                                            

The result is 2 buttons rendered. Whenever I click any button the label inside conditionaly rendered panelGroup appears but included page doesn't. If I change 'menuItem1' var from first ui:repeat it works but it is really unpredictable. For example if I hardcode setSelectedItemLabel parameter to 'page_1' then when I click to button_1 page_1 is displayed but even if I click to button_2 page_2 (!?) is displayed...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
778 views
Welcome To Ask or Share your Answers For Others

1 Answer

You're facing a view build time vs view render time problem. This is essentially the same problem which is already answered in detail in JSTL in JSF2 Facelets... makes sense? In that answer, replace "JSTL" with "ui:include". To the point, the <ui:repeat> runs during view render time, while the <ui:include> has already run during view build time before.

You'll understand that the only solution is to replace the <ui:repeat> by another tag which runs during view build time, such as JSTL <c:forEach>.

Note that I don't guarantee that it will solve the concrete functional requirement which you've in mind. Using JSTL may have undesirable "side effects" (which are however explainable, understandable and workaroundable).

See also:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...