1

我有一个组件(例如 TextField),它将根据其他选择(例如单选按钮)显示,当它被隐藏时,我不希望应用此字段上的绑定,所以

在某个地方:

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

在其他地方:

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.

我不想从布局中删除组件,因为将它放在相同的位置会是一个问题。我尝试了setVisible(false),setEnabled(false)setReadOnly(true),但都没有阻止应用绑定。有没有一种简单的方法可以做到这一点?

我正在使用 Vaadin 8。

4

2 回答 2

3

@Morfic 答案不再正确。Vaadin 8 现在支持取消​​绑定字段:

TextField usernameField;

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

binder.removeBinding(this.usernameField);
于 2018-03-13T03:27:43.403 回答
1

据我所知,一旦绑定,没有直接的方法可以防止绑定器将值设置为字段。尽管如此,您可以通过使用bind(HasValue<FIELDVALUE> field, ValueProvider<BEAN,FIELDVALUE> getter , Setter<BEAN,FIELDVALUE> setter )方法变体轻松解决此限制(?!)。

对于示例,您可以检查下面的代码。请注意,它只有基本部分来显示效果,因此它没有所有的花里胡哨,例如使用复选框禁用或重置就业日期字段:

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 +
                    '}';
        }
    }
}

结果:

如果未选中复选框,则忽略雇用日期绑定

PS:一种流利的建造者风格:

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)
      );
于 2017-07-17T15:53:11.800 回答