Vaadin 14 - пропадание сетки при использовании вложенного макета

После реализации вложенных макетов я столкнулся с проблемой рендеринга компонента, содержащего сетку. Анализ показывает, что он присутствует в html, но имеет атрибуты блока отображения, и сетка никогда не видна.

Я прочитал аналогичный вопрос (Vaadin 14 - Grid не отображение / заполнение при использовании во вложенном макете), но перечисленные там предложения не принесли мне никакого результата.

Вот мой код:

MainLayout.kt:

@Theme(value = Material::class, variant = Material.DARK)
class MainLayout : Composite<Div>(), RouterLayout {

    //Component to delegate content through.
    private val mainContent: Div = Div()
    private val layout = VerticalLayout(
            Span("from MainLayout top"),
            mainContent,
            Span("from MainLayout bottom"))


    override fun showRouterLayoutContent(hasElement: HasElement) {

        Objects.requireNonNull(hasElement)
        Objects.requireNonNull(hasElement.element)
        mainContent.removeAll()
        mainContent.element.appendChild(hasElement.element)
    }

    init {
        content.add(layout)
    }
}

LayoutWithMenuBar.kt:

@ParentLayout(value = MainLayout::class)
class LayoutWithMenuBar : Composite<Div>(), RouterLayout {

    private val mainContent: Div = Div()

    private val menuBar = HorizontalLayout(
            RouterLink("Home", MainView::class.java),
            RouterLink("Tprojects", TProjectDashboard::class.java),
            RouterLink("ViewA", ViewA::class.java),
            RouterLink("ViewB", ViewB::class.java))


    private val root = VerticalLayout(menuBar, mainContent)

    override fun showRouterLayoutContent(hasElement: HasElement) {

        Objects.requireNonNull(hasElement)
        Objects.requireNonNull(hasElement.element)
        mainContent.removeAll()
        mainContent.element.appendChild(hasElement.element)
    }


    init {

        content.add(root)
    }
}

и компонент, содержащий сетку - TProjectDashboard:

@Route("dashboard/tproject", layout = LayoutWithMenuBar::class)
class TProjectDashboard(@Autowired val tprojectService: TProjectService): VerticalLayout() {

    var tprojectGrid = Grid<TProject>(TProject::class.java)

    init {
        //tprojectGrid
        tprojectGrid.setColumns(
                TProject::tprojectUuid.name,
                TProject::tprojectClass.name,
                TProject::tprojectState.name,
                TProject::tentityState.name,
                TProject::size.name)

        tprojectGrid.setItems(tprojectService.findAll())

        tprojectGrid.setSizeFull()
        tprojectGrid.setWidthFull()
        tprojectGrid.setHeightFull()

        add(tprojectGrid)

        setSizeFull()
        setHeightFull()
        setWidthFull()
    }
}

Тот же результат, что и при изменении родительского элемента TProjectDashboard с VerticalLayout на Composite. Подход с вложенными макетами хорошо работает для простых компонентов, таких как Span, и если я удалю ссылку на макет из аннотации @Route, я увижу свою сетку.

Вот как он выглядит сейчас: введите здесь описание изображения

Буду признателен за любые подсказки или решения.

Заранее спасибо.


person Alexander Larin    schedule 06.02.2020    source источник


Ответы (1)


Вероятно, это проблема с размером, которая, к сожалению, случается слишком часто. Я бы начал с вызова setSizeFull() в mainContent div. Если это не помогает, просмотрите элементы в инструментах разработчика браузера и попытайтесь увидеть, где пропадает размер, например какой первый элемент имеет нулевую ширину или высоту.

Изменить: настройка setSizeFull() для всех компонентов работает. Однако я бы немного упростил ваши макеты, изменив композиты на тип VerticalLayout. Тогда вы сможете избавиться от большого количества setSizeFull() вызовов.

Приведенный ниже код написан на Java, поскольку у меня не настроен Kotlin, вы можете вызвать getContent().setSizeFull() в MainLayout, если хотите, чтобы он занимал всю высоту страницы.

MainLayout

@Theme(value = Material.class, variant = Material.DARK)
public class MainLayout extends Composite<VerticalLayout> implements RouterLayout {

    //Component to delegate content through.
    private Div mainContent = new Div();

    public MainLayout() {
        getContent().add(
                new Span("from MainLayout top"),
                mainContent,
                new Span("from MainLayout bottom"));
        mainContent.setSizeFull();
    }

    @Override
    public void showRouterLayoutContent(HasElement hasElement) {
        Objects.requireNonNull(hasElement);
        Objects.requireNonNull(hasElement.getElement());
        mainContent.removeAll();
        mainContent.getElement().appendChild(hasElement.getElement());
    }
}

LayoutWithMenuBar

@ParentLayout(value = MainLayout.class)
public class LayoutWithMenuBar extends Composite<VerticalLayout> implements RouterLayout {

    private Div mainContent = new Div();

    private HorizontalLayout menuBar = new HorizontalLayout(
            new RouterLink("Tprojects", TProjectDashboard.class));

    public LayoutWithMenuBar() {
        getContent().add(menuBar, mainContent);
        mainContent.setSizeFull();
    }

    @Override
    public void showRouterLayoutContent(HasElement hasElement) {
        Objects.requireNonNull(hasElement);
        Objects.requireNonNull(hasElement.getElement());
        mainContent.removeAll();
        mainContent.getElement().appendChild(hasElement.getElement());
    }
}

TProjectDashboard

@Route(value = "dashboard/tproject", layout = LayoutWithMenuBar.class)
public class TProjectDashboard extends VerticalLayout {

    private Grid<TProject> tprojectGrid = new Grid<>(TProject.class);

    public TProjectDashboard() {

        tprojectGrid.setItems(
                new TProject("Erik", "Software Engineer"),
                new TProject("Fia", "Kindergarden teacher"),
                new TProject("Jack", "All trades")
        );

        add(tprojectGrid);
    }
}
person Erik Lumme    schedule 06.02.2020
comment
Благодарю. Я попробовал то, что вы сказали - добавил setSizeFull ко всем объектам содержимого от MainLayout до моего проблемного компонента, запустил проект в чистом виде, а затем перестроил его, но это не помогло. Что касается нулевого размера, я снова посмотрел его в Mozilla, единственный способ, который я нашел, чтобы показать сетку, - это изменение стиля элементов с удалением display: block. Я совершенно не понимаю, что заставляет движок так рендерить сетку. Я видел что-то немного связанное с этой темой на одном форуме, где было высказано предположение, что проблема в скроллере и его высоте, но я еще не нашел решения. - person Alexander Larin; 06.02.2020
comment
Отредактировал свой ответ - person Erik Lumme; 07.02.2020
comment
Большое спасибо, вы были совершенно правы, извините, что зря потратил время. Я изменил Composite ‹Div› на Composite ‹VerticalLayout›, а также повторно импортировал свой проект в Idea, а затем перекомпилировал его, и он начал работать. Не уверен, в чем именно была моя ошибка - недостаточная процедура восстановления или использование Div в Composite. Большое спасибо! - person Alexander Larin; 07.02.2020
comment
Это не было пустой тратой времени, теперь это задокументировано здесь! И для этого требовалось установить полный размер для содержимого, mainLayout и вертикальных макетов, так что это было довольно сложно. - person Erik Lumme; 07.02.2020