Vaadin 14 CDI - Использование одного представления в нескольких представлениях
Я новичок в CDI и Vaadin14. Раньше мы разрабатывали в Vaadin7 Vaadin8, но никогда не использовали CDI.
Сейчас мы оцениваем Vaadin14 с CDI. Я не совсем понял, как это работает. Проблема, с которой я столкнулся на данный момент:
У меня есть вид, файл дизайна, сделанный с помощью Vaadin Designer. Которая содержит несколько макетов и сетку с почтовыми адресами. У меня есть другое представление, такое же, как и предыдущее, с отображением доменов. Когда вы выбираете один домен в сетке, открывается новый макет, содержащий вкладки. Теперь я хочу поместить представление "Почтовые адреса" на эту вкладку, чтобы показать почтовые адреса, связанные с этим выбранным доменом. Все идет нормально. Каждое представление имеет свою собственную "службу" (класс презентатора, MVP). Я ввел классы обслуживания в классы дизайна (представление).
Теперь я хочу использовать тот же Design-Class, который я использовал для просмотра почтовых адресов, в качестве компонента на моей "вкладке", который показывает мне связанные почтовые адреса с моим выбранным доменом. Но как мне вставить Mailadresses-View / Service в этот EditView? (См. EditdrawerDesign.java "@Inject MailadresseDesign mailDesign")
Получение исключения Error / NullpointerException в MailadresseDesign (см. Метод AfterNavigation)
DomainDesign.java:
@Route(value = "Domain", layout = MainView.class)
@Tag("domain-design")
@JsModule("./src/domain-design.js")
public class DomainDesign extends PolymerTemplate<DomainDesignModel> implements AfterNavigationObserver {
@Id("domainGrid")
private Grid<Domain> domainGrid;
private DomainService service;
@Id("vaadinButton")
private Button vaadinButton;
@Id("contentLayout")
private VerticalLayout contentLayout;
EditdrawerDesign editView;
ListDataProvider<Domain> dataProvider;
/**
* Creates a new DomainDesign.
*/
@Inject
public DomainDesign(@RouteScopeOwner(DomainDesign.class) DomainService service) {
this.service = service;
service.setDesign(this);
service.initListeners();
domainGrid.addColumn(Domain::getName).setHeader("Domainname").setSortable(true).setKey("name");
domainGrid.addColumn(Domain::getIsEmailDomain).setHeader("E-Mail Domain").setSortable(true).setKey("isEmail");
domainGrid.addColumn(Domain::getRegistrar).setHeader("Registrar").setSortable(true).setKey("registrar");
createEditView();
editView.addCancelListener(e -> {
editView.hide();
});
editView.addSaveListener(e -> {
editView.hide();
service.saveDomain(service.getSelectedDomain());
});
setFilters();
}
public void createEditView() {
editView = new EditdrawerDesign(service);
contentLayout.add(editView);
}
/**
* This model binds properties between DomainDesign and domain-design
*/
public interface DomainDesignModel extends TemplateModel {
// Add setters and getters for template properties here.
void setDomain(Domain domain);
String getDomain();
}
@Override
public void afterNavigation(AfterNavigationEvent event) {
// Lazy init of the grid items, happens only when we are sure the view will be
// shown to the user
dataProvider = new ListDataProvider<>(service.getDomains());
domainGrid.setDataProvider(dataProvider);
}
public void showEditView(Domain domain) {
editView.show(domain);
}
DomainService.java:
@NormalRouteScoped
@RouteScopeOwner(DomainDesign.class)
public class DomainService {
private List<Domain> domains;
private DomainDesign design;
private Domain selectedDomain;
private Binder<Domain> binder;
public DomainService() {
}
{
domains = Arrays.asList("<Dummy Data - ignore this>")
);
}
public List<Domain> getDomains() {
return domains;
}
public void setDesign(DomainDesign domainDesign) {
design = domainDesign;
}
public String getDesign() {
return design.getClass().getSimpleName();
}
public void initListeners() {
design.getDomainGrid().addSelectionListener(e->{
selectedDomain = (Domain) e.getFirstSelectedItem().get();
design.showEditView(selectedDomain);
binder.readBean(selectedDomain);
});
design.getVaadinButton().addClickListener(e -> {
Domain newDomain = new Domain();
design.showEditView(newDomain);
binder.readBean(newDomain);
});
}
public Domain getSelectedDomain() {
return selectedDomain;
}
public void bindData(EditdrawerDesign editdrawerDesign) {
binder = new Binder<>(Domain.class);
binder.forField(editdrawerDesign.getDomainName()).bind("name");
binder.forField(editdrawerDesign.getRegistrarName()).bind("registrar");
binder.bind(editdrawerDesign.getIsEmailDomain(),"isEmailDomain");
binder.bindInstanceFields(editdrawerDesign);
}
public void saveDomain(Domain domain) {
try {
binder.writeBean(domain);
} catch (ValidationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
design.getDomainGrid().getDataProvider().refreshAll();
}
}
EditdrawerDesign.java:
@Tag("editdrawer-design")
@JsModule("./src/editdrawer-design.js")
public class EditdrawerDesign extends PolymerTemplate<EditdrawerDesign.EditdrawerDesignModel> {
@Id("saveButton")
private Button saveButton;
@Id("itemName")
private H2 itemName;
@Id("cancelButton")
private Button cancelButton;
private DomainService service;
@Id("editLayout")
private VerticalLayout editLayout;
@Id("domainName")
private TextField domainName;
@Id("registrarName")
private TextField registrarName;
@Id("isEmailDomain")
private Checkbox isEmailDomain;
@Id("tabLayout")
private HorizontalLayout tabLayout;
@Id("editDomainLayout")
private VerticalLayout editDomainLayout;
@Inject
MailadresseDesign mailDesign;
/**
* Creates a new EditdrawerDesign.
*/
public EditdrawerDesign(DomainService service) {
this.service = service;
// You can initialise any data required for the connected UI components here.
service.bindData(this);
initTabs();
}
public void initTabs() {
Tab tab1 = new Tab("Domain");
Tab tab2 = new Tab("Mailadressen");
mailDesign.setVisible(false);
Map<Tab, Component> tabsToPages = new HashMap<>();
tabsToPages.put(tab1, editDomainLayout);
tabsToPages.put(tab2, mailDesign);
Tabs tabs = new Tabs(tab1, tab2);
Set<Component> pagesShown = Stream.of(editDomainLayout).collect(Collectors.toSet());
tabs.addSelectedChangeListener(event -> {
pagesShown.forEach(page -> page.setVisible(false));
pagesShown.clear();
Component selectedPage = tabsToPages.get(tabs.getSelectedTab());
selectedPage.setVisible(true);
pagesShown.add(selectedPage);
});
tabLayout.add(tabs);
editLayout.add(mailDesign);
}
/**
* This model binds properties between EditdrawerDesign and editdrawer-design
*/
public interface EditdrawerDesignModel extends TemplateModel {
// Add setters and getters for template properties here.
}
public Registration addCancelListener(ComponentEventListener<ClickEvent<Button>> listener) {
return cancelButton.addClickListener(listener);
}
public Registration addSaveListener(ComponentEventListener<ClickEvent<Button>> listener) {
return saveButton.addClickListener(listener);
}
public void setTitle(String name) {
itemName.setText(name);
}
public TextField getDomainName() {
return domainName;
}
public void setDomainName(TextField domainName) {
this.domainName = domainName;
}
public TextField getRegistrarName() {
return registrarName;
}
public void setRegistrarName(TextField registrarName) {
this.registrarName = registrarName;
}
public Checkbox getIsEmailDomain() {
return isEmailDomain;
}
public void setIsEmailDomain(Checkbox isEmailDomain) {
this.isEmailDomain = isEmailDomain;
}
public void show(Domain domain) {
getElement().getStyle().set("display", "flex");
if (domain.getName() != null) {
itemName.setText("Bearbeiten");
} else
itemName.setText("Neue Domain");
}
public void hide() {
getElement().getStyle().set("display", "none");
}
}
MailadresseDesign.java:
@Route(value = "Mailadressen", layout = MainView.class)
@Tag("mailadresse-design")
@JsModule("./src/mailadresse-design.js")
public class MailadresseDesign extends PolymerTemplate<MailadresseDesignModel> implements AfterNavigationObserver {
@Id("mailadressenGrid")
public Grid<Mailadresse> mailadressenGrid;
@Inject
private MailadressenService service;
/**
* Creates a new MailadresseDesign.
*/
public MailadresseDesign() {
mailadressenGrid.addColumn(Mailadresse::getMailadresse).setHeader("Mailadresse");
mailadressenGrid.addColumn(Mailadresse::getDomain).setHeader("Domain");
mailadressenGrid.addColumn(Mailadresse::getMailbox).setHeader("Mailbox");
mailadressenGrid.addColumn(Mailadresse::getWeiterleitung).setHeader("Weiterleitung");
}
/**
* This model binds properties between MailadresseDesign and mailadresse-design
*/
public interface MailadresseDesignModel extends TemplateModel {
// Add setters and getters for template properties here.
}
@Override
public void afterNavigation(AfterNavigationEvent event) {
**// Getting null here (service = null)**
mailadressenGrid.setItems(service.getMailadressen());
}
}
MailadresseService.java:
@ApplicationScoped
public class MailadressenService {
private List<Mailadresse> mailadressen;
{
mailadressen= Arrays.asList(<Dummy Data> - ignore this);
}
public List<Mailadresse> getMailadressen() {
return mailadressen;
}
}