扩展表单布局看起来与插入表单布局不同

Extending Form Layout looks different that inserting Form Layout

问题

我希望我的 Vaadin 组件之一使用 FormLayout。为此,该组件扩展了 FormLayout (com.vaadin.flow.component.formlayout.FormLayout)。该组件将 class 间接扩展到另一个 class(不应真正破坏行为)。奇怪的是它没有按预期工作。它并排显示布局中的所有元素,即使列数已定义。

import com.example.application.model.Memory;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.html.Span;

// AbstractPcPartCard extends FormLayout
@Tag("memory-component")
public class MemoryCard extends AbstractPcPartCard {
    private static final long serialVersionUID = -8954098740536795286L;
    Memory pcPart;

    public MemoryCard(Memory pcPart) {
        this.pcPart = pcPart;

        Span name = new Span(pcPart.getName());
        Span price = new Span(this.getPrice());
        Span stock = new Span(this.getStock());
        Span config = new Span(this.getConfiguration());
        Span form = new Span(this.getFormFactor());
        Span frequency = new Span(this.getFrequency());

        setResponsiveSteps(
            new ResponsiveStep("0", 3),
            new ResponsiveStep("1200px", 6));

        add(name, price, stock, config, form, frequency);
        // we should not need to add a layout, because the component itself is the layout.
    }
    // getters
}

这是它的样子: everything side by side

hacky 解决方案

如果我在组件中创建一个新的 FormLayout 并将其添加到组件中,它会正常工作。所以在某种程度上,我现在在 Formlayout 中有一个 FormLayout。在这种情况下,组件本身不需要扩展 FormLayout。扩展组件 (com.vaadin.flow.component.formlayout.FormLayout) 就足够了。

import com.example.application.model.GraphicsCard;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.html.Span;

import java.util.stream.Collectors;

@Tag("graphics-card-component")
public class GraphicsCardCard extends AbstractPcPartCard {
    private static final long serialVersionUID = -5813124388374902829L;

    GraphicsCard pcPart;

    public GraphicsCardCard(GraphicsCard pcPart) {
        this.pcPart = pcPart;

        FormLayout layout = new FormLayout();

        Span name = new Span(pcPart.getName());
        Span price = new Span(this.getPrice());
        Span stock = new Span(this.getStock());
        Span model = new Span(this.getCardModel());
        Span connections = new Span(this.getConnections());
        Span pci = new Span(this.getPciExpressVersion());
        Span cooling = new Span(this.getCoolingSystem());

        layout.add(name, price, stock, model, connections, pci, cooling);
        layout.setColspan(connections, 2);

        layout.setResponsiveSteps(
                new FormLayout.ResponsiveStep("0", 3),
                new FormLayout.ResponsiveStep("1200px", 6));

        // here we add the FormLayout to the FormLayout
        add(layout);
    }
    // getters 
}

这应该是这样的: inserted form layout

我的愿望

我认为作为FormLayout 本身的组件比创建包含FormLayout 的组件优雅得多。如何修复我的 FormLayout 以在列中显示数据?

源代码

可以在 github 上找到示例项目的完整源代码。 github example project 相关视图和组件可以在包中找到:com.example.application.ui.views.partsComponent

源代码包含其他视图,其中一些也有问题,例如使用 dom-if 的视图,以使用不同的模板渲染器。但这是关于堆栈溢出的另一个问题。

为 FormLayout 定义的 CSS 以标记 <vaadin-form-layout> 为目标,但您已通过 @Tag("memory-component") 更改了标记。因此,您将丢失所有样式。

这是一个说明差异的工作示例:

@Route
public class TestFormExtendView extends Div {

public TestFormExtendView() {
    JustExtend justExtend = new JustExtend();
    justExtend.add(new Button("Button1"), new Button("Button2"));
    add(justExtend);

    ExtendAndChangeTag extendAndChangeTag = new ExtendAndChangeTag();
    extendAndChangeTag.add(new Button("Button3"), new Button("Button4"));
    add(extendAndChangeTag);
}

public static class JustExtend extends FormLayout {}

@Tag("extend-and-change-tag")
public static class ExtendAndChangeTag extends FormLayout {}

因此您可以扩展布局,但不要更改标签。

建议: 我有时通过扩展 Vaadin 布局来构建领域特定组件,但现在只有在我添加布局通用功能时才这样做。相反,我继续为领域特定组件扩展非布局组件。我认为布局特别是为组合而不是扩展而设计的,你最好不要反对它。