【问题标题】:Strategy for lazy-loading tab content in a TabSheet in Vaadin 7在 Vaadin 7 的 TabSheet 中延迟加载选项卡内容的策略
【发布时间】:2014-12-23 01:18:53
【问题描述】:

我正在寻找一种仅在选择选项卡之后而不是之前将内容加载到 Vaadin TabSheet 上的选项卡的方法。 Lazy Loading,就是这个词。

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

我在 Vaadin 论坛上阅读了主题 Strategy for creating lazy load tabs。我确实从Jens Jansson 那里了解到,在客户端,Vaadin 已经是延迟加载了。在选择选项卡之前,不会在浏览器中填充 DOM。但我担心减轻服务器端的负载。那个线程没有解决那个问题。

【问题讨论】:

  • 将虚拟面板放入其中,并捕获 TabSelected 事件(左右)以构建真实视图

标签: java tabs lazy-loading vaadin vaadin7


【解决方案1】:

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

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

更新 也可以继承 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();
        }
    }
}

}

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

【讨论】:

  • 为什么要扩展CustomComponent?为什么不继承TabSheet
  • 举个简单的例子重要吗?这不是我的生产就绪代码,而是帮助某人的快速方法。为自己定制代码或忽略它,你的电话。
  • 不是批评,而是一个严肃的问题。我不清楚 CustomComponent 的用途。我想知道通过子类化 TabSheet 来采用您的方法是可能/可取的。
  • 查看更新(在您的评论之前编辑:P)。这里没有特别的理由避免继承。碰巧我是这样写样本的。仔细考虑它最好将标签表子类化,这样您也可以使用常规标签并拥有 TabSheet 的所有操作。请注意,这里急切的 LazyTabs 和常规选项卡是不同的,因为 LazyTabs 会重新加载。
  • 很棒的答案。我想补充一点,你的 LazyTab 也可以是一个界面。这样一来,每个选项卡都可以自己实现它,但它会允许选项卡本身扩展它喜欢的任何内容,例如 VerticalLayout、CustomComponent 或 CssLayout。此外,在您拥有选项卡表的类中,您可以引用选项卡本身,有时更容易玩快速'n'dirty,只需处理 selectedTabChange 中的所有逻辑。你可以把一个临时的组件放到tab里面,比如CssLayout,然后在selectedTabChange里面初始化真实的view,切换出来。
【解决方案2】:

这是一个编译上述一些建议的实现:

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

【讨论】:

    猜你喜欢
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多