Most ismerkedek a Vaadinnal.Azt a feladatot kaptam, hogy alakítsak ki olyan kódbázist, amiben újra felhasználható elemek vannak.
Itt viszont állandó küzdés volt eddig.
A lényeg a kód, így mutatok példát:
public class AComponent extends VerticalLayout implements MyComponent {
private static final String PERSON = "Személy";
private static final String ORGANIZATION = "Szervezet";
private ADto aDto = new ADto();
private ComboBox<String> type = new ComboBox<>();
private PersonComponent personComponent;
private OrganizationComponent organizationComponent;
private Binder<ADto> binder = new BeanValidationBinder<>(ADto.class);
public AComponent(String title) {
binder.forField(type).bind(ADto::getType, ADto::setType);
//binder.bindInstanceFields(true);
binder.setBean(aDto);
add(new H3(title));
setPadding(false);
type.setPlaceholder("<válasszon>");
type.setItems(PERSON, ORGANIZATION);
add(type);
VerticalLayout sumbitterDataContainer = new VerticalLayout();
sumbitterDataContainer.setPadding(true);
sumbitterDataContainer.setSpacing(false);
add(sumbitterDataContainer);
type.addValueChangeListener(listener -> {
if (isPerson()) {
personComponent = new PersonComponent(sumbitterDataContainer);
} else {
organizationComponent = new OrganizationComponent(sumbitterDataContainer);
}
});
}
@Override
public boolean validate() {
boolean valid = binder.validate().isOk();
if (valid && isPerson()) {
valid = personComponent.validate();
}
if (valid && isOrganization()) {
valid = organizationComponent.validate();
}
return valid;
}
private boolean isOrganization() {
return ORGANIZATION.equals(type.getValue());
}
private boolean isPerson() {
return PERSON.equals(type.getValue());
}
}
public class PersonComponent extends VerticalLayout implements MyComponent {
private PersonDto personDto = new PersonDto();
private NameComponent personName = new NameComponent("Viselt név");
private NameComponent birthName = new NameComponent("Születési név");
private Binder<PersonDto> binder = new BeanValidationBinder<>(PersonDto.class);
public PersonComponent(FlexComponent container) {
binder.bindInstanceFields(this);
binder.setBean(personDto);
addDataFields(container);
}
@Override
public boolean validate() {
return binder.isValid() && personName.validate() && birthName.validate();
}
private void addDataFields(final FlexComponent container) {
container.removeAll();
container.add(personName, birthName);
}
}
public class PersonDto {
private NameDto personName;
private NameDto birthName;
private NameDto mothersName;
private BirthplaceDto birthplace;
private LocalDate birthdate;
// getters, setters...
}
public class ADto {
@NotNull
@NotEmpty
@NotBlank
@Size(min = 1)
private String type;
private PersonDto personDto;
private OrganizationDto organizationDto;
// getters, setters...
}
Azaz pl. van egy névbekérő rész ami ismétlődhet több formon is.
Körülnéztem a Vaadin oldalán is, de csak egyszerű példák vannak. Ahol mindent feldobálsz egy form-ra, és nem használsz újra részeket. Kerestem Google-el is, de nem találtam komolyabb példákat.
1.) Az elképzelésem az volt, hogy A dto-kon levő annotációkkal tudom kontrollálni a felületen megjelenő hibaüzeneteket.
Tehát ha pl. kötelező megadni a AComponent type lenyílóját, ha pl. rákattint egy gombra amivel mentené a formot és validálja is közben a validate metódussal, akkor majd szépen kiírja a hibaüzenetet, hogy "nem lehet üres" a type mező alá. De ez nem történik meg. :( Látható, hogy ráraktam szinte minden létező annotációt. De a binder.isValid() azt mondja valid, amikor null az értéke.
2.) Valamint eredetileg arra gondoltam, hogy biztos van valami automatizáció, amely egy ilyen Component tree-n végig tud menni és a bevitt adatokból létrehoz egy ADto-t, benne a PersonDto-val, benne a NameDto-kkal stb. Úgy tűnik ilyen nincs. :(
Az is lehet csak rossz helyen kutatok és van valami egyszerű megoldás is, ami működik is.
Van valakinek valami megoldása erre?
- 180 megtekintés
Hozzászólások
Az 1.)-re megvan a megoldás. Mivel az automatikus bind nem működött, ezért a bind-nak nekem kell megadnom a validátort. Így működik, bár így elég össze-vissza lesz minden, hiszen egyszer a dto-kban számít ha van rajta annotáció, máskor nem.
A 2)-at megoldom akkor, hogy végig megyek a component tree-n, de ház ez is elég gáz, hogy itt is vegyesen lesz a bind.
Elég gányolt lesz így a kód. Aminek nem örülök. :(
- A hozzászóláshoz be kell jelentkezni
Eleve büdös nekem amikor valaki egy framework fölé akar építeni még egy superframework réteget.
Szerintem még nézegess vaadinos projekteket, tutorialokat, fórumokat.
https://vaadin.com/docs/v14/flow/tutorial/forms-and-validation
zászló, zászló, szív
- A hozzászóláshoz be kell jelentkezni
Nem szeretnék külön frameworkot fejleszteni fölé. Egyszerűen csak újra felhasználható form részeket szeretnék, pl. a példában a névre. Ahol a név több mezőből állhat. Ezért kerestem volna valakit, aki nap mint nap használja, hátha van valami ami nincs a tutorialokban, de van értelmes megoldás.
Ami feltűnt, hogy nem jó a komponenesek átgondoltsága sem. Pl. ha több checkbox-od van és mindegyik kötelező, akkor egyenként bele kell rakni egy-egy CheckboxGroup-ba, hogy normálisan megjelenjen mellettük a kis piros hibaüzenet. Ez az egész framework ilyennek tűnik. Azaz nem gondolták át jól a fejlesztők mire lehet igény.
- A hozzászóláshoz be kell jelentkezni
Nem ismerem a technikai részleteket de a Vaadin egy nagyon régi, nagyon sokak által használt framework, nem biztos hogy egy-két nap nézegetés után levonnék ilyen következtetést.
zászló, zászló, szív
- A hozzászóláshoz be kell jelentkezni
Hidd el, én is csodálkoztam, hogy ilyen alapvető gondok vannak. Ráadásul többször felmerült igény a checkbox-oknál a felhasználók részéről. Egyszer még MR-t is adott fel rá valaki. Ha pl. erre rákeresel a neten. akkor 2 féle megoldást kapsz: 1. saját megoldás készítése ( https://github.com/vaadin/flow-components/issues/3397 - ezt kipróbáltam - voltak vele hibák pl. a hibaüzenet eltűnt, ha kattintottál valahova az oldalon). 2. A checkboxgroup-os megoldás - ez egyelőre működik.
- A hozzászóláshoz be kell jelentkezni