如何多次手动实例化一个viewscoped bean

时间:2017-04-20 19:19:00

标签: java jsf primefaces

我正在使用JSF构建一个单页应用程序,如下所示:

home page preview

左侧的菜单是动态生成的,点击其中一个子菜单会创建一个标签,我在其中显示<ui:include>的内容。

菜单和标签代码:

<p:layoutUnit position="west" resizable="false" size="210">
    <h:form id="menu_form">
        <p:panelMenu style="width:200px" model="#{homeView.menu}" />
    </h:form>
</p:layoutUnit>

<p:layoutUnit id="center-layout" position="center">

    <p:tabView id="tabss" style="font-size: 15px"
        activeIndex="#{homeView.index}" scrollable="true">
        <p:ajax event="tabClose" listener="#{homeView.onTabClose}"
            update="tabss" />
        <p:ajax event="tabChange" listener="#{homeView.onTabChange}"
            update="tabss" />

        <c:forEach items="#{homeView.openTabs}" var="otab">
            <p:tab title="#{otab.title}" closable="true"
                style="font-size: 15px" rendered="#{otab.open}">
                <p:scrollPanel mode="native" styleClass="scrollPanels">
                    <ui:include src="#{otab.content}" />
                </p:scrollPanel>
            </p:tab>
        </c:forEach>
    </p:tabView>
</p:layoutUnit>

主页的支持bean:

@ManagedBean
@ViewScoped
public class HomeView {

    private List<Tab> tabs;
    private List<Tab> openTabs;
    private int index;
    private TabService tabService;
    private MenuService menuService;
    private MenuModel menu;
    @ManagedProperty("#{loginView}")
    private LoginView loginView;

    @PostConstruct
    public void init() {
        tabService = new TabService();
        menuService = new MenuService();
        tabs = menuService.loadTabs(loginView.getUtilisateur().getProfile());
        openTabs = new ArrayList<Tab>();
        menu = menuService.loadMenu(loginView.getUtilisateur().getProfile());
    }

    public void addTab(String title) {
        if (tabService.check(openTabs, title)) {
            openTabs = tabService.addTab(tabs, openTabs, title);
        }
        if (tabService.getIndex(openTabs, title) != -1) {
            index = tabService.getIndex(openTabs, title);
        }
    }

    public void onTabClose(TabCloseEvent event) {
        String title = event.getTab().getTitle();
        String ti = openTabs.get(index).getTitle();
        openTabs = tabService.closeTab(openTabs, title);
        if (ti.equals(title)) {
            index = tabService.setIndex(index);
        } else {
            index = tabService.setIndex(openTabs, ti);
        }
    }

    public void onTabChange(TabChangeEvent event) {
        index = tabService.getIndex(openTabs, event.getTab().getTitle());
    }
    // Getters and setters

我应该注意,点击子菜单会调用方法addTab(Title)来打开标签页 每个包含的页面(显示在选项卡中)都使用自己的视图结构bean,在关闭选项卡后将其销毁(参见上面的代码)。

有问题:

在上面的屏幕截图中,我展示了一个标签,我在<p:dataTable>中显示搜索结果,我想要的行为是:
每当从dataTable中选择一个元素时,我想打开一个Tab,我将在其中显示有关所述元素的更多信息。对我来说重要的是能够同时打开多个Tab(显示有关元素的更多信息) 我想到的是创建一个将执行显示部分的xhtml,以及一个用于支持所述页面的视图结构bean。那么有没有办法手动实例化所述bean(每次用户点击按钮时),然后用相应的数据填充它,这样我可以多次重复使用同一页面?
感谢

2 个答案:

答案 0 :(得分:1)

作为一种解决方法,您可以为多个信息页面请求使用相同的viewscoped bean。打开信息页面时,您可以将标识符作为参数传递。例如,1,2分别用于信息页面1和2,并通过标识符将任何相关数据存储在集合中,并相应地在页面中进行变量绑定。

答案 1 :(得分:0)

如果我很清楚你想要做什么,一种可能性就是以编程方式用视图作用域bean来评估表达式:

FacesContext context = FacesContext.getCurrentInstance();
ExpressionFactory expressionFactory = context.getApplication().getExpressionFactory();
ELContext elContext = context.getELContext();
ValueExpression vex = expressionFactory.createValueExpression(elContext, "#{viewBeanName}", ViewBeanClass.class);
ViewBeanClass viewBean = (ViewBeanClass) vex.getValue(elContext);

如果它不存在,那将会实例化bean,如果它确实存在,它将返回它。