Question

My application structure goes like this

template.xhtml

<html>  
    <h:body>  
       <f:view>    
           <p:layout fullPage="true">  
             <p:layoutUnit position="center">  
                <ui:insert name="content"/> 
            </p:layoutUnit>  

            <p:layoutUnit position="south" size="50" style="bottom:0px;" gutter="0" collapsible="true">  
               <ui:include src="footer.xhtml"/>  
            </p:layoutUnit>  
          </p:layout>  
      </f:view>  
   </h:body></html>

menu.xhtml

<ui:composition template="../templates/template.xhtml">
    <ui:define name="content">  
    <p:tabView id="contentTabView" dynamic="true" cache="false" activeIndex="0">  
       <p:tab id="tab1" />  
       <p:tab id="tab2" />  
       .  
       .  
       <p:tab id="tabn" />  
    </p:tabView>  
   </ui:define>  
</ui:composition>    

There is only one <f:view> in my application which is in template file.

Since I have put dynamic="true" in tabView I thought only tab1 should be loaded and corresponding view scoped bean should be created.

When I launched my application what I observed was all the view scoped beans respective to each tab is created and put in UIViewRoot's viewMap.

And I have only one view in my application menu.xhtml and that is the reason no
view scoped bean is getting destroyed when I am switching between the tabs.

Is there any way to ensure that only the beans referred in the active tab are only instantiated?

Was it helpful?

Solution

I've done something similar with different results.

<h:form id="tabForm">
    <p:tabView id="tabView" dynamic="true" cache="false">  
        <p:tab id="tba1" title="Tab 1">  
            #{viewMBean1.hello}
        </p:tab>  
        <p:tab id="tab2" title="Tab 2">  
            #{viewMBean2.hello}
        </p:tab>  
    </p:tabView>  
</h:form>  

On my managed beans I've written the following methods:

@PostConstruct
public void setup() {
    System.out.println("ViewMBean1");
}

@PostConstruct
public void setup() {
    System.out.println("ViewMBean2");
}

This is what the console shows when loading the page:

ViewMBean1

I noticed that, once loaded, the view beans are not removed from view scope when changing tabs. This may be something you don't want to happened. In that case you could remove the beans from view scope through a change listener.

<p:ajax event="tabChange" listener="#{tabViewManager.onTabChange}" process="@this" global="false" />

On TabViewManager:

public void onTabChange(TabChangeEvent event) {
    Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
    viewMap.remove("viewMBean1");
    viewMap.remove("viewMBean2");
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top