簡體   English   中英

Vaadin 21 流。 如何遷移曾經有一個帶邊框的面板的 CustomLayout

[英]Vaadin 21 flow. How to migrate CustomLayout used to have a panel with border

使用 vaadin 7(我們正在嘗試遷移到 v21,非常非常困難)我們有這個

CustomLayout cl1 = new CustomLayout(new ByteArrayInputStream("<fieldset><legend location='legend'></legend><div location='content'></div></fieldset>".getBytes()));
cl1.setSizeUndefined();
cl1.add(new Label(title), "legend");
cl1.add( panel, "content");

基本上是一個帶有邊框和標題邊框的面板我們如何在 vaadin flow v21 中做到這一點

提前致謝

Vaadin 10+ 為最常用的 HTML 標簽定義了“元素”,並為構建在這些元素之上的組件提供了更高級別的抽象。 它不包括<fieldset>的元素或組件。 我不熟悉 Vaadin 7,但看起來它也沒有附帶。

有幾種方法可以使用 Vaadin 10+ 執行您想要的操作。 下面是一個基於擴展Component類的快速示例:

@Tag("fieldset")
public class FieldSet extends Component {

    private final Div enclosedComponents;

    public FieldSet(String label) {
        Element legend = new Element("legend").setText(label);
        getElement().appendChild(legend);
        enclosedComponents = new Div();
        getElement().appendChild(enclosedComponents.getElement());
    }

    public void add(Component ... components) {
        enclosedComponents.add(components);
    }
}

我沒有包含一個強大的 API。 完全補充 add 和 remove 方法以及更新標簽的方法會更有用。

作為學習 10+ 的一個點,要知道fieldset的性質使這個變得更加復雜。 如果這不必包含<legend>標簽,它可能會簡單得多,因為您可以簡單地擴展Div或幾個Layout類之一並繼承一個健壯的 API。

文檔中有一部分概述了解決這些類型問題的各種方法。 當我第一次開始使用 Vaadin 時,我發現它非常寶貴。 何時使用每種方法並不總是很清楚,但您會感覺到它。

有一個食譜配方為 CustomLayout 提供了替代方案: https : //cookbook.vaadin.com/custom-layout

本質上,CustomLayout 替換類以一種相當直接的方式擴展了Html add方法具有大部分邏輯:

public class CustomLayout extends Html {
    private Map<String, Component> locations = new HashMap<>();

    public CustomLayout(String template) {
        super(template);
    }

    public CustomLayout(InputStream stream) {
        super(stream);
    }

    public void add(Component child, String location) {
        remove(location);
        locations.put(location, child);

        // Establish parent-child relationship, but leave DOM attaching to us
        getElement().appendVirtualChild(child.getElement());

        // Attach to the specified location in the actual DOM
        getElement().executeJs("this.querySelector('[location=\"'+$0+'\"]').appendChild($1)", location,
                child.getElement());

        // Ensure the element is removed from the DOM when it's detached
        child.addDetachListener(detachEvent -> {
            detachEvent.unregisterListener();
            getElement().executeJs("this.querySelector && this.querySelector('[location=\"'+$0+'\"]').lastChild.remove()", location);

            // Also clear the bookkeeping
            locations.remove(location, child);
        });
    }

    public void remove(String location) {
        Component oldChild = locations.remove(location);
        if (oldChild != null) {
            remove(oldChild);
        }
    }

    public void remove(Component child) {
        getElement().removeVirtualChild(child.getElement());
    }
}

請注意,使用locations Map 進行簿記很重要,以便在分離父元素后也刪除客戶端元素。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM