【问题标题】:Dynamic Page loading using <ui:include> is initializing beans only once使用 <ui:include> 的动态页面加载仅初始化 bean 一次
【发布时间】:2013-03-28 04:22:18
【问题描述】:

我正在使用 ajax 和 primefaces 布局动态加载页面。这是我的页面。

index.xhtml

<p:layout fullPage="true">
            <p:layoutUnit position="north">
                <h1>Header</h1>
            </p:layoutUnit>

            <p:layoutUnit position="south">
                <h1>Footer</h1>
            </p:layoutUnit>

            <p:layoutUnit position="west">
                <h:form>

                    <p:menu>
                        <p:menuitem value="Page1" action="#{navigationBean.method('page1')}"
                                    ajax="true" update=":main-content"/>
                        <p:menuitem value="Page2" action="#{navigationBean.method('page2')}"
                                    ajax="true" update=":main-content"/>
                    </p:menu>
                </h:form>
            </p:layoutUnit>

            <p:layoutUnit position="center" >

                <h:panelGroup id="main-content">
                    <ui:include src="#{navigationBean.page}.xhtml" />
                </h:panelGroup>

            </p:layoutUnit>
        </p:layout>

NavigationBean.java

@ManagedBean
@SessionScoped
public class NavigationBean {

    @ManagedProperty(value="page1")
    private String page;

public String getPage() {
        return page;
    }

    public void setPage(String page) {
        this.page = page;
    }

    public void method(String page){
        this.page = page;
    }
}

page1.xhtml

<h:outputText value="#{page1Bean.text}"/>

page2.xhtml

<h:outputText value="#{page2Bean.text}"/>

Page1Bean.java

@ManagedBean
@SessionScoped
public class Page1Bean {

    private String text;

    @PostConstruct
    public void init()
    {
        System.out.println("\nPage1Bean @PostConstruct");;
    }

    public Page1Bean() {
        text = "Page 1 BEan Text Variable";
        System.out.println("Page1Bean Constructor");
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

}

Page2Bean.java 类似于 Page1Bean.java。 该代码工作正常,可以动态加载页面并使用 ajax。 但问题是 @PostConstruct 和 Page1Bean 和 Page2Bean 的构造函数只被调用一次。 我的意思是第一次加载页面时会调用这些方法。 但是第二次加载页面时不会再次调用它们。 因此,如果有人以前做过或见过它,请帮助我如何处理这种情况。

编辑:我已经根据 Luiggi Mendoza 的想法在 Page1Bean 和 Page2Bean 上尝试了 @Viewscope,但仍然没有运气。 它对@REQUESTSCOPE 很好(感谢 Luiggi Mendoza),但是如果将来我得到一些 @SESSIONSCOPE bean 怎么办??

【问题讨论】:

  • 如果您想在每次页面加载时都实例化一个 bean,那么该 bean 应该是一个请求范围。Viewscope 就像该特定视图的 sessionscoped bean。所以,如果您想要新的每次页面加载时实例我猜请求范围是唯一的选择。
  • @SrinivasR @RequestScoped 将在同一页面上的每个请求(包括 ajax 请求)上创建。似乎@ViewScoped 可以解决这个问题,因为每次访问页面时都会创建 bean:第一次访问、第二次访问、从不同选项卡访问、刷新页面等。
  • 我不明白你问题的最后一部分:如果将来我得到一些@SESSIONSCOPE bean。您可以在@RequestScoped 中注入@SessionScoped 托管bean,如您的代码所示,因此完全没有问题。另外,请尝试一个更详细的示例,而不是仅仅从一个页面导航到另一个页面,以真正了解@RequestScoped 和@ViewScoped 之间的区别。

标签: jsf primefaces


【解决方案1】:

将范围从 @SessionScoped 更改为更窄的范围,例如 @ViewScoped 或 @RequestScoped。对于这种情况,@ViewScoped 似乎符合您的目的。

BalusC 在他的博客文章Communication in JSF 2: Managed Bean Scopes 中解释了每个 JSF 托管 bean 范围的详细信息。

【讨论】:

    猜你喜欢
    • 2012-01-22
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    • 2011-09-14
    • 2020-12-28
    • 1970-01-01
    相关资源
    最近更新 更多