Vaadin 14 CDI - Использование одного представления в нескольких представлениях - PullRequest
0 голосов
/ 02 марта 2020

Я новичок в CDI и Vaadin14. Раньше мы разрабатывали в Vaadin7 Vaadin8, но никогда не использовали CDI.

Теперь мы оцениваем Vaadin14 с CDI. Я не совсем понял, как это работает. Проблема, с которой я сталкиваюсь на данный момент:

У меня есть представление, Design-File, созданное с помощью Vaadin Designer. Который содержит несколько макетов и сетку с почтовыми адресами. У меня есть другой вид, такой же, как предыдущий, показывающий домены. Когда вы выбираете один домен в сетке, открывается новый макет, который содержит вкладки. Теперь я хочу поместить представление «Почтовые адреса» на эту вкладку, чтобы показать почтовые адреса, связанные с выбранным доменом. Все идет нормально. У каждого представления есть свой «Сервис» (Presenter Class, MVP). Я ввел классы обслуживания в классы дизайна (представление).

Теперь я хочу использовать тот же класс дизайна, который я использовал для представления почтовых адресов, в качестве компонента в моей «вкладке», который показывает мне связанные почтовые адреса. в мой домен я выбрал. Но как я могу внедрить 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;

}
}
...