简体   繁体   中英

How to manually instantiate a viewscoped bean multiple times

I'm building a one page app with JSF that looks something like this :

主页预览

The menu on the left is dynamically generated and clicking on one of the submenu creates a tab in which I display content from an <ui:include> .

Menu and tabs code :

<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>

Backing bean for the home page :

@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

I should note that clicking on the submenus calls the methode addTab(Title) to open the tab
Each of the included page (the one displayed in the tabs) uses its own viewscoped bean which is destroyed after closing the tab (see the above code).

Problematic :

In the above screenshot I showed a tab in which I display a search result in a <p:dataTable> , the behavior I want is :
Whenever an element is selected from the dataTable, I want to open a Tab where I will display more info about the said element. What is important to me is being able to open more than one Tab(that displays more info about an element) at the same time.
What I have in mind is creating an xhtml which will do the displaying part, and a viewscoped bean to back the said page. So is there a way to manually instantiate the said bean (everytime the user clicks on the button) and then populate it with the corresponding data, that way I can re-use the same page multiple times ?
Thanks

As a workaround you could have the same viewscoped bean for multiple info page requests. When you open an info page you can pass an identifier as a parameter. For eg., 1,2 for info page one and two respectively and store any associated data in a collection by the identifier and do the variable binding in the page accordingly.

If I understand well what you want to do, one possibility is to evaluate an expression with the view scoped bean, programatically:

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);

That is going to instantiate the bean if it doesn't exists, if it does exist, it will return it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM