我正在寻找一种方法,只有在选中标签而不是之前,才能将内容加载到Vaadin标签页上的标签中。 Lazy Loading,是术语。
Vaadin 7 Tabsheet的延迟加载并不明显,因为在构建时需要每个标签的内容。
我在Vaadin论坛上阅读了帖子Strategy for creating lazy load tabs。我确实向Jens Jansson学习,在客户端,Vaadin已经懒惰了。在选择选项卡之前,不会在浏览器中填充DOM。但我担心缓解服务器端的负载。该线程无法解决该问题。
答案 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();
}
}
}
}