gpt4 book ai didi

jsf - 如何延迟加载与 p :Tab, 中包含的页面关联的 ManagedBean 仅在打开 Tab 时

转载 作者:行者123 更新时间:2023-12-05 00:26:10 27 4
gpt4 key购买 nike

我有一个 p:tabViewp:accordionPanel和 Facelets 包含在每个 p:tab 中使用 ui:include .
我的问题是与每个包含的页面相关联的 ManagedBeans 在启动时初始化,我怎样才能让它们仅在打开特定选项卡时初始化。
这是代码示例:
索引.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>

页面1.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
}

}

在上面的例子中 #{bean1}#{bean2}在加载时初始化 index.xhtml本身。
打开的默认选项卡是 Tab1 所以很明显 #{bean1}已加载但为什么 #{bean2} ??
我发布这个问题的主要原因是在标签之间传输数据,所以如果有任何替代方法,请建议我。

*使用:Primfaces 3.5 和 JSF 2.*1

最佳答案

如果您希望延迟加载选项卡内容,为什么不遵循至少在 showcase example 中提供的模式? (同样适用于 <p:tabView> )?重复那个例子(注意 dynamic="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 树中 ( View 渲染时间)尽管面板组永远不会被渲染,因为 View 正在被渲染( <ui:include> 属性)之前的生命周期事件中被构建( rendered taghandler)。同样,以下代码段产生了预期的效果,如 <c:if><ui:include>是标签处理程序:
<c:if test="#{bean.tab eq 1}">
<ui:include src="page1.xhtml"/>
</c:if>

最终,如果 PrimeFaces <p:accordionPanel>决定在 View 渲染时渲染什么, View 构建时间标签也将被评估(这是你的情况),所以你可以通过包含一个小 <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>

关于jsf - 如何延迟加载与 p :Tab, 中包含的页面关联的 ManagedBean 仅在打开 Tab 时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19088522/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com