问题
Using Vaadin 14.0.13 without compatibility mode.
I use a view to create a Dialog with dynamic content:
@Route("")
public class MainView extends VerticalLayout {
public MainView(DialogContentProvider contentProvider) {
this.add(new Button("Click me!", event -> new Dialog(contentProvider.create()).open()));
}
}
The contentProvider
is an interface
public interface DialogContentProvider {
Component create();
}
with this implementation:
public class CheckBoxContentProvider implements DialogContentProvider {
@Override
public Component create() {
return new Checkbox("My checkbox", true);
}
}
instantiated by Spring Boot (version 2.2.1.RELEASE) with a bean:
@Bean
public DialogContentProvider contentProvier() {
return new CheckBoxContentProvider();
}
When I click on the button, the dialog is opened but the checkbox haven't the box:
The source code is on github: https://github.com/gronono/bug-vaadin-checkbox
I don't understand why and how I can fix it. If I include the checkbox creation inside the main view, it works fine:
@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()));
}
}
回答1:
This sound an awful lot like this (related github issue)
Basically, this happens when you don't have any View that uses a Checkbox directly, but through other means like reflection or in your case the contentProvider, because in no view of your app there is any import statement of Checkbox
(--> therefore, vaadins scan during the installation will not detect usages of Checkbox
, so it will not download npm stuff for checkbox).
in the github it says this will be fixed in 14.1
If you need a fix now, for me it worked when I declared a field of that type in any view with a @Route. That field doesn't have to be used.
@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()));
}
}
Addendum: This is not related to the Checkbox
component specifically, it happens with any vaadin component that isn't initially scanned in a route, but used anyway through reflective-, provider-, or generic means.
Edit: You can also work around this currently by adding a @Route(registerAtStartup = false)
to your provider that uses the Checkbox directly. This will make vaadins scan see the checkbox usage (therefore importing its npm package), but will not actually register the provider as a real route..
Another way which I prefer if you need this for multiple components is to create a new View with a @Route(registerAtStartup = false)
which only defines private variables for each component that you'll need in the application (and arent already used directly in some view of yours). This has the advantage of all these component usage definitions in one place, and once the official fix is released, you need only to delete one class and the deprecated workaround is gone.
@Route(registerAtStartup = false)
public class ComponentImportView extends VerticalLayout {
private Checkbox checkBox;
private Upload upload;
private ProgressBar progressBar;
}
来源:https://stackoverflow.com/questions/59025629/vaadin-checkbox-is-not-correctly-rendered