Tengo un componente (por ejemplo, un TextField) que se mostrará dependiendo de alguna otra selección, un botón de radio, por ejemplo, y cuando está oculto no quiero que se aplique el enlace en este campo, así que

En algun lugar:

Binder binder = new Binder<SomeDTO>(SomeDTO.class);
TextField conditionalComponet = TextField("A conditional component: ");
binder.bind(conditionalComponet, "propertyX");

Y en algún otro lugar:

SomeDTO someDTO = new SomeDTO;
binder.writeBean(someDTO); //Here propertyX shouldn't be filled, i.e. bind should 
                       //not be applied, to propertyX of SomeDTO if the 
                       //conditionalComponet is hidden.

No me gustaría eliminar el componente del diseño, ya que colocarlo en la misma posición será un problema. Intenté setVisible(false), setEnabled(false) y setReadOnly(true), pero ninguno impide que se aplique el enlace. ¿Existe una forma sencilla de hacerlo?

Estoy usando Vaadin 8.

1
VitorCruz 14 jul. 2017 a las 02:28

2 respuestas

La mejor respuesta

Hasta donde yo sé, no hay una forma directa de evitar que el enlazador establezca un valor en un campo, una vez que esté enlazado. No obstante, puede solucionar esta limitación (?!) Fácilmente, utilizando el campo bind (HasValue , ValueProvider getter, Variante del método Setter setter) .

Para obtener una muestra, puede consultar el código a continuación. Tenga en cuenta que solo tiene las partes básicas para mostrar el efecto, por lo que no tiene todas las campanas y silbatos, como deshabilitar o restablecer el campo de fecha de empleo con la casilla de verificación:

import com.vaadin.data.Binder;
import com.vaadin.data.ValidationException;
import com.vaadin.ui.*;

import java.io.Serializable;
import java.time.LocalDate;

public class DisableBindingForField extends VerticalLayout {
    private final Person person = new Person("Dark Vaper");
    private final TextField name = new TextField("Name:");
    private final CheckBox isEmployed = new CheckBox("Is employed:");
    private final DateField dateOfEmployment = new DateField("Date of employment:");
    private final Binder<Person> binder = new Binder<>(Person.class);
    private final Button button = new Button("Save");

    public DisableBindingForField() {
        // manually bind the custom field separately (https://vaadin.com/docs/-/part/framework/datamodel/datamodel-forms.html - scroll to the end)
        binder.bind(dateOfEmployment, person -> person.dateOfEmployment, (person, dateOfEmployment) ->
                // if the check-box is checked then populate the pojo with the value, otherwise reset the pojo value to null
                person.setDateOfEmployment((isEmployed.getValue()) ? dateOfEmployment : null)
        );

        // automatically bind the rest of the fields
        binder.bindInstanceFields(this);

        // initial reading of the bean
        binder.readBean(person);

        // add components to the user interface
        addComponents(name, isEmployed, dateOfEmployment, button);

        // simulate a "save button"
        button.addClickListener(event -> {
            try {
                binder.writeBean(person);
                Notification.show(person.toString());
            } catch (ValidationException e) {
                e.printStackTrace();
            }
        });
    }

    // basic pojo for binding
    public class Person implements Serializable {

        private String name;
        private Boolean isEmployed;
        private LocalDate dateOfEmployment;

        public Person(final String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(final String name) {
            this.name = name;
        }

        public boolean isEmployed() {
            return isEmployed;
        }

        public void setEmployed(boolean employed) {
            isEmployed = employed;
        }

        public LocalDate getDateOfEmployment() {
            return dateOfEmployment;
        }

        public void setDateOfEmployment(LocalDate dateOfEmployment) {
            this.dateOfEmployment = dateOfEmployment;
        }

        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", isEmployed=" + isEmployed +
                    ", dateOfEmployment=" + dateOfEmployment +
                    '}';
        }
    }
}

Resultado:

ignore employment date binding if check-box is not checked

P.D .: Estilo alternativo fluent-builder :

binder.forField(dateOfEmployment)
      .bind(person -> person.dateOfEmployment, (person, dateOfEmployment) ->
          // if the check-box is checked then populate the pojo with the value, otherwise reset the pojo value to null
          person.setDateOfEmployment((isEmployed.getValue()) ? dateOfEmployment : null)
      );
1
Morfic 17 jul. 2017 a las 15:53

La respuesta de @Morfic ya no es correcta. Vaadin 8 ahora admite desvincular un campo:

TextField usernameField;

binder.forField(this.usernameField)
    .bind(User::getUsername, User::setUsername);

binder.removeBinding(this.usernameField);
2
nyr1o 13 mar. 2018 a las 06:22