Vaadin 复选框未正确呈现

Vaadin checkbox is not correctly rendered

在没有兼容模式的情况下使用 Vaadin 14.0.13。

我使用一个视图来创建一个包含动态内容的对话框:

@Route("")
public class MainView extends VerticalLayout {

   public MainView(DialogContentProvider contentProvider) {
      this.add(new Button("Click me!", event -> new Dialog(contentProvider.create()).open()));
   }
}

contentProvider是一个接口

public interface DialogContentProvider {
    Component create();
}

使用此实现:

public class CheckBoxContentProvider implements DialogContentProvider {
    @Override
    public Component create() {
        return new Checkbox("My checkbox", true);
    }
}

由 Spring 引导(版本 2.2.1.RELEASE)用 bean 实例化:

    @Bean
    public DialogContentProvider contentProvier() {
        return new CheckBoxContentProvider();
    }

当我点击按钮时,对话框打开但复选框没有:

源码在github:https://github.com/gronono/bug-vaadin-checkbox

我不明白为什么以及如何解决它。如果我在主视图中包含复选框创建,它工作正常:

@Route("")
public class MainView extends VerticalLayout {

    public MainView(DialogContentProvider contentProvider) {
//        this.add(new Button("Click me!", event -> new Dialog(contentProvider.create()).open()));
        this.add(new Button("Click me!", event -> new Dialog(new Checkbox("My checkbox", true)).open()));
    }
}

这听起来很像 this (related github issue)

基本上,当您没有任何直接使用 Checkbox 的视图,而是通过其他方式(如反射)或在您的情况下使用 contentProvider 时,就会发生这种情况,因为在您的应用程序的视图中没有 Checkbox(--> 因此,安装期间的 vaadins 扫描将不会检测 Checkbox 的用法,因此它不会为复选框下载 npm 内容)。
在 github 它说这将在 14.1

中修复

如果您现在需要修复,对我来说,当我在任何视图中使用@Route 声明该类型的字段时,它就起作用了。不必使用该字段。

@Route("")
public class MainView extends VerticalLayout {
    private Checkbox unusedCheckbox; // this line fixes it. 

    public MainView(DialogContentProvider contentProvider) {
        this.add(new Button("Click me!", event -> new Dialog(contentProvider.create()).open()));
    }
}

附录:这与具体的 Checkbox 组件无关,它发生在任何最初未在路由中扫描但无论如何通过反射、提供者或通用方式使用的 vaadin 组件.

编辑:您目前还可以通过向直接使用复选框的提供商添加 @Route(registerAtStartup = false) 来解决此问题。这将使 vaadins 扫描看到复选框的使用(因此导入它的 npm 包),但实际上不会将提供程序注册为真实路由。


如果您需要多个组件,我更喜欢的另一种方法是创建一个带有 @Route(registerAtStartup = false) 的新视图,其中 为您定义的每个组件定义私有变量在应用程序中需要(并且在您的某些观点中已经 直接 使用)。这样做的好处是所有这些组件使用定义都在一个地方,一旦官方修复发布,你只需要删除一个 class 并且不推荐使用的解决方法就消失了。

@Route(registerAtStartup = false)
public class ComponentImportView extends VerticalLayout {
    private Checkbox checkBox;
    private Upload upload;
    private ProgressBar progressBar;
}