0

Initialize view model of a tab only after user clicks on it

asked 2023-09-16 16:38:41 +0800

newborn gravatar image newborn
3 2

updated 2023-09-18 08:53:52 +0800

Hello everyone,

I'm currently working on a page with multiple tabs.

<?init class="org.zkoss.zk.ui.util.Composition" arg0="layout/_mainLayout.zul"?>
<?component name="tabA" macroURI="/component/tabA.zul" inline="true"?>
<?component name="tabB" macroURI="/component/tabB.zul" inline="true"?>
<zk>
    <div self="@define(content)" apply="org.zkoss.bind.BindComposer">
        <div>
            <tabbox>
                <tabs>
                    <tab label="A" disable="false"/>
                    <tab label="B" disable="false"/>
                </tabs>
                <tabpanels>
                    <tabpanel>
                        <tabA/>
                    </tabpanel>
                    <tabpanel>
                        <tabB/>
                    </tabpanel>
                </tabpanels>
            </tabbox>
        </div>
    </div>
</zk>

tabA.zul

<zk>
    <div apply="org.zkoss.bind.BindComposer"
         viewModel="@id('vm') @init('com.TabAVM')">
        <vlayout>
            <button label="Refresh"/>
        </vlayout>
    </div>
</zk>

The tabs function perfectly, but there's a challenge: all the ViewModel (VM) for the tabs initialize as soon as the page loads. There's a particularly resource-intensive code in the @AfterCompose section of some tabs, like "tab b", which I'd prefer not to execute every time the page loads. Additionally, certain users don't have permissions to access some tabs, so pre-loading these tabs for them is unnecessary. Ideally, the VM for each tab should initialize only when the user clicks on that particular tab.

Does anyone have suggestions on how to achieve this, or is there a better solution I might consider?

delete flag offensive retag edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2023-09-18 23:09:14 +0800

HenningBlohm gravatar image HenningBlohm
118 1

You if you can load the view in tabB programmatically, then you could add a ON_SELECT listener to the Tab tab that loads and sets the view as child of the Tabpanel panel on first selection.

I.e. if view.get() creates the view, and tab is the Tab object, and panel is the corresponding Tabpanel, then

Tabpanel panel = ...
Tab tab = ...
EventListener onSelect = e->{
  SelectEvent se = (SelectEvent) e;
  if (se.getSelectedItems().contains(tab)) {
    if (panel.getChildren().isEmpty()) {
      panel.getChildren().add(view.get());
    }
  }
};
tab.addEventListener(Events.ON_SELECT, onSelect);
link publish delete flag offensive edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2023-09-16 16:38:41 +0800

Seen: 4 times

Last updated: Sep 18

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More