-->

Rich TabPanel's getters invoked when tab conte

2019-04-01 03:29发布

问题:

I have a question about RichFace's (3.3.3) TabPanel. I have worked on two projects that have used the TabPanel. On each project, I have noticed that components that are on tabs that are not visible still have their "getter" methods called.

For example, the first tab has a datatable on in and any time requests are made from any of the other tabs (including ajax requests) the bean that is bound to the datatable on the first tab still has its getter called.

I assume this happens (even though the tab is currently not rendered in the UI) because the component is still in the component hierarchy? In other words, all components are children of the parent tab panel and so are processed on each request..even if they aren't visible.

Ok...if my assumption is true, then I need a way to not have data retrieval logic invoked for tabs that aren't being used. I've read the postings about lazily loading data (not putting data retrieval logic in the getter) because the getters may be called many times. I'm doing my best to adhere to that; the problem that I'm seeing is that even though I have the bean that is bound to the table (on tab one) defined with request scope and the getter is lazily loading the data for the table, the bean gets instantiated, and the data pulled (lazily), on each ajax request from other tabs.

There's got to be a way around this short of pulling all content out of the RichFace's TabPanel and rolling my own.

I tried making the bean bound to the table session scoped and "caching" the data that the getter returns to the table, but the problem there is that there is no lifecycle method to bind to for when the tab gets rendered again (either via manually clicking the tab or programmatically selecting the tab).

I'd appreciate any suggestions.

回答1:

The tabPanel has an attribute called selectedTab that calls a getter/setter every time a tab is selected. You could use the setter method to refresh the data when a specific tab is selected. You could also prevent the calling of getter methods within each tab by wrapping the content of the tab within a c:if element, which stops that segment of the html if the test returns false. For example:

<ui:composition 
    xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:rich="http://richfaces.org/rich
    xmlns:c="http://java.sun.com/jstl/core">
    <rich:tabPanel selectedTab="#{pageScopedBean.selectedTab}">
        <rich:tab id="particularTab" label="A Tab">
            <c:if test="#{pageScopedBean.selectedTab eq 'particularTab'}">
                <!-- tab contents -->
            </c:if>
        </rich:tab>
    </rich:tabPanel>
</ui:composition>

Then within the Java, create getter and setter methods on pageScopedBean:

@Name("pageScopedBean")
@Scope(ScopeType.PAGE)
public class PageScopedBean {
    private String selectedTab = "";
    public String getSelectedTab() {
        return selectedTab;
    }
    public void getSelectedTab(String selectedTab) {
        this.selectedTab = selectedTab;
        if (this.selectedTab == "particularTab") {
            // refresh table
        }
    }