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");
基本上是一个带边框的面板 title-border
我们如何在 vaadin flow v21
中做到这一点
提前致谢
Vaadin 10+ 为最常用的 HTML 标签定义了“元素”,并对构建在这些元素之上的组件进行了更高级别的抽象。它不包括 <fieldset>
的元素或组件。我对 Vaadin 7 不熟悉,但它似乎也没有附带。
有多种方法可以使用 Vaadin 10+ 执行您想要的操作。这是一个基于扩展 Component
class:
的快速示例
@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。完全补充添加和删除方法以及更新标签的方法会更有用。
作为学习 10+ 的一个要点,要知道 fieldset
的性质使这个更加复杂。如果这不必包含 <legend>
标记,它可能会简单得多,因为您可以简单地扩展 Div
或几个 Layout
classes 之一并继承一个健壮的API.
有一个 section of the documentation 概述了解决这些类型问题的各种方法。当我第一次开始使用 Vaadin 时,我发现它非常宝贵。何时使用每种方法并不总是很清楚,但您会体会到的。
有一个 Cookbook 食谱为 CustomLayout 提供了替代方案:https://cookbook.vaadin.com/custom-layout
本质上,CustomLayout 替换 class 以相当直接的方式扩展了 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=\"'+[=10=]+'\"]').appendChild()", 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=\"'+[=10=]+'\"]').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
映射进行簿记很重要,这样在父元素分离后客户端元素也会被删除。
使用 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");
基本上是一个带边框的面板 title-border 我们如何在 vaadin flow v21
中做到这一点提前致谢
Vaadin 10+ 为最常用的 HTML 标签定义了“元素”,并对构建在这些元素之上的组件进行了更高级别的抽象。它不包括 <fieldset>
的元素或组件。我对 Vaadin 7 不熟悉,但它似乎也没有附带。
有多种方法可以使用 Vaadin 10+ 执行您想要的操作。这是一个基于扩展 Component
class:
@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。完全补充添加和删除方法以及更新标签的方法会更有用。
作为学习 10+ 的一个要点,要知道 fieldset
的性质使这个更加复杂。如果这不必包含 <legend>
标记,它可能会简单得多,因为您可以简单地扩展 Div
或几个 Layout
classes 之一并继承一个健壮的API.
有一个 section of the documentation 概述了解决这些类型问题的各种方法。当我第一次开始使用 Vaadin 时,我发现它非常宝贵。何时使用每种方法并不总是很清楚,但您会体会到的。
有一个 Cookbook 食谱为 CustomLayout 提供了替代方案:https://cookbook.vaadin.com/custom-layout
本质上,CustomLayout 替换 class 以相当直接的方式扩展了 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=\"'+[=10=]+'\"]').appendChild()", 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=\"'+[=10=]+'\"]').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
映射进行簿记很重要,这样在父元素分离后客户端元素也会被删除。