4

I have a p:tabView or p:accordionPanel and Facelets included in each p:tab using ui:include.
My Problem is ManagedBeans associated with each included page are Initialized on starting itself, How can I make them Initialize only when the particular Tab is opened.
Here is the code Sample: index.xhtml

<p:tabView dynamic="true" cache="true">
   <p:tab title="Bean 1 Page 1">
    <ui:include src="page1.xhtml"/>
   </p:tab>

   <p:tab title="Bean 2 Page 2">
    <ui:include src="page2.xhtml"/>
   </p:tab>
</p:tabView>

page1.xhtml

<h:body>
    <f:metadata>
    <f:event listener="#{bean1.bean1PreRender}" type="preRenderView"/>
    </f:metadata>
    <h:form>
    <h:outputLabel value="#{bean1.bean1Text}"/>
    </h:form>
</h:body>

Bean1.java

@ManagedBean
@ViewScoped
public class Bean1 implements Serializable{
    private String bean1Text = "Hello From Bean 1";
    public Bean1() {
        System.out.println("Bean 1 Constructor");
    }
    @PostConstruct
    public void init(){
        System.out.println("Bean 1 @PostConstruct");
    }
    public void bean1PreRender(){
            System.out.println("Bean 1 PreRender PostBack Call");
        if(!FacesContext.getCurrentInstance().isPostback()){
            System.out.println("Bean 1 PreRender NON PostBack Call");
        }
    }
    //SETTER GETTER
}

page2.xhtml

<h:body>
    <f:metadata>
    <f:event listener="#{bean2.bean2PreRender}" type="preRenderView"/>
    </f:metadata>
    <h:form>
    <h:outputLabel value="#{bean2.bean2Text}"/>
    </h:form>
</h:body>

Bean2.java

    @ManagedBean
    @ViewScoped
    public class Bean2 implements Serializable{
        private String bean2Text = "Hello From Bean 2";
        public Bean2() {
            System.out.println("Bean 2 Constructor");
        }
        @PostConstruct
        public void init(){
            System.out.println("Bean 2 @PostConstruct");
        }
        public void bean2PreRender(){
                System.out.println("Bean 2 PreRender PostBack Call");
            if(!FacesContext.getCurrentInstance().isPostback()){
                System.out.println("Bean 2 PreRender NON PostBack Call");
            }
        }
        //SETTER GETTER
    }

}

In the above example #{bean1} and #{bean2} are initialized on loading index.xhtml itself.
Default tab opened is Tab1 so it is obvious that #{bean1} is loaded but why #{bean2} ??
The main reason I'm posting this question is to transfer the data between Tabs, So if there is any alternative way is there then please suggest me.

*Using : Primfaces 3.5 and JSF 2.*1

4

1 に答える 1

2

タブ コンテンツを遅延読み込みする場合は、少なくともショーケースの例で提供されているパターンに従ってください(同じことが にも当てはまります<p:tabView>)。その例を繰り返すには (notedynamic="true"属性):

<h:form>  
    <p:accordionPanel dynamic="true" cache="true">  
        <p:tab title="Bean 1 Page 1">
            <ui:include src="page1.xhtml"/>
        </p:tab>
        <p:tab title="Bean 2 Page 2">
            <ui:include src="page2.xhtml"/>
        </p:tab>
    </p:accordionPanel>
</h:form>

その理由は、JSF コンポーネント ツリーを構築するときに、含まれているすべてのページ コンテンツがそのツリーに含まれてしまうため、対応する Bean が初期化されるためです。同じことが次の例でも発生します。

<h:panelGroup rendered="false">
    <ui:include src="page1.xhtml"/>
</h:panelGroup>

上記のコードでは、コンテンツは JSF コンポーネント ツリーに含まれますが(ビューのビルド時)、HTML DOM ツリーには含まれません(ビューのレンダリング時)。ただし、ビューがビルドされているため、パネル グループは決してレンダリングされません。 ( <ui:include>taghandler) がレンダリングされる前のライフサイクルイベント (rendered属性)。同様に、次のスニペットは、 と の両方がタグハンドラであるため、目的の効果をもたらし<c:if>ます<ui:include>

<c:if test="#{bean.tab eq 1}">
    <ui:include src="page1.xhtml"/>
</c:if>

最終的に、PrimeFacesがビューのレンダリング時に何をレンダリングするかを決定する場合、ビューのビルド時のタグも評価<p:accordionPanel>されます (これはあなたの場合です)。<c:if>. キックオフの例:

<h:form>  
    <p:accordionPanel dynamic="true" cache="true">
        <p:tab title="Bean 1 Page 1">
            <c:if test="#{component.parent.activeIndex eq 0 or empty component.parent.activeIndex}">
                <ui:include src="page1.xhtml"/>
            </c:if>
        </p:tab>
        <p:tab title="Bean 2 Page 2">
            <c:if test="#{component.parent.activeIndex eq 1}">
                <ui:include src="page2.xhtml"/>
            </c:if>
        </p:tab>
    </p:accordionPanel>
</h:form>
于 2013-09-30T08:39:41.013 に答える