禁用 Vaadin 绑定
Disable a Vaadin Binding
我有一个组件(例如 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)
,但 none 阻止应用绑定。有简单的方法吗?
我正在使用 Vaadin 8。
据我所知,没有直接 方法可以防止值在绑定后被活页夹设置为字段。尽管如此,您可以通过使用 bind(HasValue field, ValueProvider<BEAN,FIELDVALUE> getter, Setter<BEAN,FIELDVALUE> setter)[=31= 轻松解决此 limitation(?!) ] 方法变体。
您可以查看下面的代码作为示例。请注意,它只有显示效果的基本部分,因此它没有所有花哨的功能,例如使用复选框禁用或重置就业日期字段:
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 +
'}';
}
}
}
结果:
P.S.:替代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)
);
@Morfic 答案不再正确。 Vaadin 8 现在支持取消绑定字段:
TextField usernameField;
binder.forField(this.usernameField)
.bind(User::getUsername, User::setUsername);
binder.removeBinding(this.usernameField);
我有一个组件(例如 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)
,但 none 阻止应用绑定。有简单的方法吗?
我正在使用 Vaadin 8。
据我所知,没有直接 方法可以防止值在绑定后被活页夹设置为字段。尽管如此,您可以通过使用 bind(HasValue
您可以查看下面的代码作为示例。请注意,它只有显示效果的基本部分,因此它没有所有花哨的功能,例如使用复选框禁用或重置就业日期字段:
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 +
'}';
}
}
}
结果:
P.S.:替代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)
);
@Morfic 答案不再正确。 Vaadin 8 现在支持取消绑定字段:
TextField usernameField;
binder.forField(this.usernameField)
.bind(User::getUsername, User::setUsername);
binder.removeBinding(this.usernameField);