Jsf ManagedBean视图范围为两页

Jsf ManagedBean视图范围为两页,jsf,Jsf,我想要什么:使用一个范围为两个不同页面的托管bean视图 原因:在一页中,我只从数据库中获得一个列表。我不想要另一个只做这件事的托管bean 场景: import javax.annotation.PostConstruct; import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedProperty; import javax.faces.bean.ViewScoped; import javax.faces.con

我想要什么:使用一个范围为两个不同页面的托管bean视图

原因:在一页中,我只从数据库中获得一个列表。我不想要另一个只做这件事的托管bean

场景:

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

@ManagedBean
@ViewScoped
public class MyManagedBean implements Serializable {

    @PostConstruct
    public void inicio() {

        //used in page page1.xhtml
        if (FacesContext.getCurrentInstance().getViewRoot().getViewId().contains("page1")) {
            methodDoThingsPage1();
        }

        //used in page2.xhtml
        if (FacesContext.getCurrentInstance().getViewRoot().getViewId().contains("page2")) {
            methodDoThingsPage2();
        }
    }

    public String detail(Object object) {
        do(object);
        return "page2?faces-redirect=true";
    }
}
托管bean:

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

@ManagedBean
@ViewScoped
public class MyManagedBean implements Serializable {

    @PostConstruct
    public void inicio() {

        //used in page page1.xhtml
        if (FacesContext.getCurrentInstance().getViewRoot().getViewId().contains("page1")) {
            methodDoThingsPage1();
        }

        //used in page2.xhtml
        if (FacesContext.getCurrentInstance().getViewRoot().getViewId().contains("page2")) {
            methodDoThingsPage2();
        }
    }

    public String detail(Object object) {
        do(object);
        return "page2?faces-redirect=true";
    }
}
我的页面:

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

@ManagedBean
@ViewScoped
public class MyManagedBean implements Serializable {

    @PostConstruct
    public void inicio() {

        //used in page page1.xhtml
        if (FacesContext.getCurrentInstance().getViewRoot().getViewId().contains("page1")) {
            methodDoThingsPage1();
        }

        //used in page2.xhtml
        if (FacesContext.getCurrentInstance().getViewRoot().getViewId().contains("page2")) {
            methodDoThingsPage2();
        }
    }

    public String detail(Object object) {
        do(object);
        return "page2?faces-redirect=true";
    }
}
我的页面1.xhtml


我的想法:当我单击
page1
中的按钮时,只有postconstruct中的
方法ThingsPage2
将被触发。但是,
methodDoThingsPage1
methodDoThingsPage2
这两种方法都被触发


怎么了?如果detail方法重定向到
page2
为什么
methodDoThingsPage1
也被激发?

使用这种方式初始化jsf托管bean,而不是
@PostConstruct

<f:metadata>
    <f:viewAction action="#{MyManagedBean.init}"/>
</f:metadata>


将这些行添加到jsf文件的开头,并从托管bean中删除
@PostConstruct
注释。

这样做是一种非常糟糕的做法。您应该有两个单独的托管bean


想想看。。你真的认为你应该在代码中加入大量的
if
条件吗?您还使用了视图的名称,这可能会导致很多问题。如果修改视图的名称会怎么样?您应该在使用代码的任何地方修改代码。

在类似的情况下,我在两个页面中使用一个基类作为常用工作,并从中继承两个
managedbean
s。比使用if要好,但这样您确实有多个managedbean。(还有另一个类)

好了,解决了

问题是字符串“page1”和“page2”正在另一段URL中使用。 然后我用了:

FacesContext.getCurrentInstance().getViewRoot().getViewId().endsWith("page1.xhtml");


使用它是一种更好的实践吗?有一次我在托管bean中遇到了
@PostConstruct
问题,这是一个解决方案。我只是想,你的问题可能有另一个解决办法。