Стратегия отложенной загрузки содержимого вкладок в TabSheet в Vaadin 7

1

Я ищу способ загрузить контент в вкладку на вкладке Vaadin TabSheet только после того, как вкладка будет выбрана, а не раньше. Ленивый Loading, это термин.

Ленивая загрузка из Vaadin 7 Tabsheet не является очевидным, что содержание каждой вкладки требуется во время строительства.

Я прочитал статью " Стратегия создания ленивых загрузочных вкладок" на форумах Vaadin. Я узнал от Йенса Янсона, что на стороне клиента Ваадин уже ленив. DOM не заполняется в браузере до тех пор, пока не будет выбрана вкладка. Но я обеспокоен ослаблением нагрузки на серверной стороне. Этот поток не решает эту проблему.

  • 0
    Поместите в него фиктивную панель и поймайте событие TabSelected (или около того), чтобы создать реальный вид
Теги:
tabs
vaadin
lazy-loading
vaadin7

2 ответа

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

}

Если вы хотите использовать аккордеон таким же образом, я бы не подклассифицировал вкладку, а реализовал функциональность через шаблон декоратора. Аккордеонные подклассы TabSheet, поэтому он должен управляться.

  • 0
    Зачем расширять CustomComponent ? Почему не подкласс TabSheet ?
  • 1
    Имеет ли это значение для быстрого примера? Это не мой готовый код, а быстрый способ помочь кому-то. Настройте код под себя или проигнорируйте его, ваш звонок.
Показать ещё 4 комментария
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();
            }
        }
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню