是否可以将视图范围bean创建仅限制为选项卡视图中的活动选项卡

时间:2014-01-15 11:10:48

标签: jsf jsf-2 primefaces jsf-2.2 view-scope

我的应用程序结构就像这样

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>    

我的应用程序中只有一个<f:view>位于模板文件中。

由于我在tabView中输入了dynamic =“true”,我认为只应加载tab1并应创建相应的视图范围bean。

当我启动我的应用程序时,我观察到的是创建了每个选项卡的所有视图范围bean并将其放入UIViewRoot's viewMap

我的申请menu.xhtml中只有一个观点,这就是原因 当我在标签之间切换时,视图范围的bean正在被破坏。

有没有办法确保只实例化活动选项卡中引用的bean?

1 个答案:

答案 0 :(得分:0)

我做了类似的不同结果。

<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>  

在我的托管bean上,我编写了以下方法:

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

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

这是控制台在加载页面时显示的内容:

ViewMBean1

我注意到,一旦加载,在更改选项卡时,视图bean不会从视图范围中删除。这可能是你不想发生的事情。在这种情况下,您可以通过更改侦听器从视图范围中删除bean。

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

在TabViewManager上:

public void onTabChange(TabChangeEvent event) {
    Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
    viewMap.remove("viewMBean1");
    viewMap.remove("viewMBean2");
}