Vaadin 7中TabSheet中延迟加载选项卡内容的策略

时间:2014-12-23 01:18:54

标签: java tabs lazy-loading vaadin vaadin7

我正在寻找一种方法,只有在选中标签而不是之前,才能将内容加载到Vaadin标签页上的标签中。 Lazy Loading,是术语。

Vaadin 7 Tabsheet的延迟加载并不明显,因为在构建时需要每个标签的内容。

我在Vaadin论坛上阅读了帖子Strategy for creating lazy load tabs。我确实向Jens Jansson学习,在客户端,Vaadin已经懒惰了。在选择选项卡之前,不会在浏览器中填充DOM。但我担心缓解服务器端的负载。该线程无法解决该问题。

2 个答案:

答案 0 :(得分:5)

这是一个完整的例子。它可以在以后封装在专用类中。请注意,每次选择的选项卡内容都会更改。如果你需要延迟加载但每次都不需要刷新,我会创建一个布尔加载字段并使刷新依赖于它。直观地说,你可以通过提供渴望的构造函数参数来使标签急切。例如,它对于第一个显示的选项卡很有用。

import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.TabSheet.SelectedTabChangeEvent;
import com.vaadin.ui.TabSheet.SelectedTabChangeListener;
import com.vaadin.ui.TextField;


public class TablesFrame extends CustomComponent {
private static class LazyTabChangeListener implements SelectedTabChangeListener {
    @Override
    public void selectedTabChange(SelectedTabChangeEvent event) {
        LazyTab tab = (LazyTab) event.getTabSheet().getSelectedTab();
        tab.refresh();
    }
}


private abstract class LazyTab extends CustomComponent {
    public LazyTab() {
        this(false);
    }


    public LazyTab(boolean eager) {
        if (eager) {
            refresh();
        }
    }


    abstract Component build();


    public final void refresh() {
        setCompositionRoot(build());
    }
}

private LazyTab tab1 = new LazyTab(true) {
    @Override
    Component build() {
        return new TextField("1");
    };
};

private LazyTab tab2 = new LazyTab() {
    @Override
    Component build() {
        return new TextField("2");
    };
};


public TablesFrame() {
    TabSheet ts = new TabSheet();
    ts.addSelectedTabChangeListener(new LazyTabChangeListener());
    ts.addTab(tab1, "Tab1");
    ts.addTab(tab2, "Tab2");
    setCompositionRoot(ts);
}
}

UPDATE 也可以将TabSheet子类化。这样您也可以使用常规选项卡并完成TabSheet的所有操作。请注意,急切的LazyTabs和常规标签在这里是不同的,因为LazyTabs会重新加载。

import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.TabSheet;


public class LazyTabSheet extends TabSheet {

public LazyTabSheet() {
    addSelectedTabChangeListener(new LazyTabChangeListener());
}


public static abstract class LazyTab extends CustomComponent {
    public LazyTab() {
        this(false);
    }


    public LazyTab(boolean eager) {
        if (eager) {
            refresh();
        }
    }


    public abstract Component build();


    public final void refresh() {
        setCompositionRoot(build());
    }
}


private static class LazyTabChangeListener implements SelectedTabChangeListener {
    @Override
    public void selectedTabChange(SelectedTabChangeEvent event) {
        Component selectedTab = event.getTabSheet().getSelectedTab();
        if (selectedTab instanceof LazyTab) {
            ((LazyTab) selectedTab).refresh();
        }
    }
}

}

如果你想以相同的方式使用手风琴,我不会将tabheet子类化,而是通过装饰器模式实现功能。 Accordion子类TabSheet因此它应该是可管理的。

答案 1 :(得分:0)

以下是编译上述一些建议的实现:

public abstract class LazyTab {

    Component comp;
    private boolean eager;
    private boolean cached;

    public static LazyTab of(boolean eager, boolean cached, Supplier<Component> componentSupplier) {

        return new LazyTab(eager, cached) {

            @Override
            protected Component build() {
                return componentSupplier.get();
            }
        };
    }

    protected LazyTab(boolean eager, boolean cached) {

        this.eager  = eager;
        this.cached = cached;

        if (eager) comp = build();
    }

    protected abstract Component build();


    public final void refresh() {
        if ((comp == null) ||!cached) comp = build();
    }

    /**
     * @return get component on demand (depends on eager and cached properties)
     */
    public final Component getComponent() {
        return comp;
    }


    public static class LazyTabSheet extends TabSheet {

        public LazyTabSheet() {
            addSelectedTabChangeListener(new LazyTabChangeListener());
        }
    }

    public static class LazyTabChangeListener implements TabSheet.SelectedTabChangeListener {

        @Override
        public void selectedTabChange(TabSheet.SelectedTabChangeEvent event) {

            Component selectedTab = event.getTabSheet().getSelectedTab();

            if (selectedTab instanceof LazyTab) {
                ((LazyTab) selectedTab).refresh();
            }
        }
    }
}