[英]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.